home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / !groovygames! / zerogravity / zerogravity.source < prev   
Text File  |  1997-05-11  |  146KB  |  5,462 lines

  1. ; *****************************************************************************
  2. ;
  3. ; $VER: ZeroGravity Source 1.0 (C) 1997 Matthijs Hollemans
  4. ;
  5. ; *****************************************************************************
  6. ;
  7. ; This is the full source code to Zero Gravity. I used the very cool ASM-One
  8. ; V1.29 assembler from T.F.A. but that doesn't matter anyway because you won't
  9. ; be able to reassemble this without the required binary includes...
  10. ;
  11. ; *****************************************************************************
  12.  
  13. SHOW    equ    0        ; 1 = Show rastertiming,   0 = Don't
  14. DEBUG    equ    1        ; 1 = Debug-mode on,       0 = Normal
  15. ASMOne    equ    1        ; 1 = Assemble for ASMOne, 0 = Make executable
  16.  
  17. run    IFNE    ASMOne        ;
  18.          jsr    Init        ;
  19.           illegal        ; 
  20.        ELSE            ;
  21.          jsr    WBInit        ;
  22.          jsr    Init        ;
  23.          jsr    WBDone        ;
  24.       rts            ; 
  25.        ENDC            ;
  26.  
  27. ; =============================================================================
  28. ;
  29. ;          S Y S T E M   S T A R T U P / E X I T   R O U T I N E S
  30. ;
  31. ; =============================================================================
  32.  
  33. ; *****************************************************************************
  34. ; Macros
  35. ; *****************************************************************************
  36.  
  37. CLRMEM     MACRO                ; Clear memory pool size 
  38. memptr     set 0                ; 
  39.        ENDM                ;
  40.        
  41. ADDMEM     MACRO                ; Request memory
  42. \1     set memptr            ; \1 = Offset in memory pool
  43. memptr     set memptr+\2            ; \2 = Size of required memory
  44.        ENDM                ;
  45.  
  46. ALIGNLONG MACRO                ; Align to longword
  47.     CNOP    0,4            ;
  48.     ENDM                ;
  49.  
  50. ALIGNQUAD MACRO                ; Align to quadword
  51.     CNOP    0,8            ;
  52.     ENDM                ;
  53.  
  54.  
  55. ; *****************************************************************************
  56. ; WBInit
  57. ; *****************************************************************************
  58.  
  59. WBInit    clr.l    ReturnMsg        ;
  60.     move.l    $4.w,a6            ;
  61.     sub.l    a1,a1            ;
  62.     jsr    -294(a6)        ; FindTask(NULL)
  63.     move.l    d0,a4            ;
  64.     tst.l    $ac(a4)            ; Called from CLI?
  65.     bne.b    .Done            ;
  66.  
  67.     move.l    $4.w,a6            ;
  68.     lea    $5c(a4),a0        ; pr_MsgPort
  69.     jsr    -384(a6)        ; WaitPort()   
  70.     lea    $5c(a4),a0        ; pr_MsgPort
  71.     jsr    -372(a6)        ; GetMsg()     
  72.     move.l    d0,ReturnMsg        ; Save message for later reply
  73. .Done    
  74.     rts
  75.  
  76.  
  77. ; *****************************************************************************
  78. ; WBDone
  79. ; *****************************************************************************
  80.  
  81. WBDone     tst.l    ReturnMsg        ; Called from CLI ?
  82.     beq.b    .Done            ; Then skip next bit
  83.  
  84.     move.l    $4.w,a6            ;
  85.     jsr    -132(a6)            ; Forbid()
  86.     move.l    ReturnMsg,a1        ; Send message back
  87.     jsr    -378(a6)            ; ReplyMsg()
  88. .Done    
  89.     move.l    ReturnCode,d0        ; Returncode
  90.     rts
  91.  
  92.  
  93. ; *****************************************************************************
  94. ; Init 
  95. ; *****************************************************************************
  96.  
  97. Init    ; Open libraries ------------------------------------------------------
  98.  
  99.     move.l    $4.w,a6            ;
  100.        lea     intname,a1        ;
  101.        moveq     #0,d0            ;
  102.        jsr     -552(a6)         ; OpenLibrary()
  103.        move.l     d0,intuibase        ;
  104.        beq.w     nointui            ;
  105.  
  106.        lea     grafname,a1        ;
  107.        moveq     #0,d0            ;
  108.        jsr     -552(a6)        ; OpenLibrary()
  109.        move.l     d0,gfxbase        ;
  110.        beq.w     nogfx            ;
  111.  
  112.     lea    dosname,a1        ;
  113.     moveq    #0,d0            ;
  114.     jsr    -552(a6)        ; OpenLibrary()
  115.     move.l    d0,dosbase        ;
  116.     beq.w    nodos            ;
  117.  
  118.     ; Check for AGA -------------------------------------------------------
  119.  
  120.     move.l    gfxbase,a6        ;
  121.     btst.b    #2,$ec(a6)        ; gb_ChipRevBits0
  122.     beq.w    noaga            ;
  123.         
  124.     ; Allocate chip memory ------------------------------------------------
  125.  
  126.        move.l     $4.w,a6            ;
  127.        move.l     #chip+65536,d0        ; (64k border because of slow copper)
  128.        move.l     #$2,d1            ; MEMF_CHIP
  129.        jsr     -198(a6)        ; AllocMem()
  130.        move.l     d0,chipmem        ;
  131.        beq.w     nochip             ;
  132.  
  133.     ; Allocate other memory -----------------------------------------------
  134.  
  135.        move.l     #fast+8192,d0         ; (8k border for 040 caches)
  136.        move.l     #$10000,d1        ; MEMF_CLEAR
  137.        jsr     -198(a6)        ; AllocMem()
  138.        move.l     d0,fastmem        ;
  139.        beq.w     nofast            ;
  140.  
  141.     ; Close Workbench -----------------------------------------------------
  142.  
  143.     IFEQ    ASMOne            ;
  144.       move.l    intuibase,a6        ;
  145.     jsr    -78(a6)            ; CloseWorkBench()
  146.     move.l    d0,wbclosed        ; Store result
  147.     ENDC                ;
  148.     
  149.     ; Reset screen hardware -----------------------------------------------
  150.     
  151.        move.l     gfxbase,a6        ;
  152.        move.l     $22(a6),oldview        ; gb_ActiView
  153.        sub.l     a1,a1            ;
  154.        jsr     -222(a6)         ; LoadView(NULL)
  155.     jsr    -270(a6)        ; WaitTOF() 
  156.     jsr    -270(a6)        ; WaitTOF()
  157.        jsr    -228(a6)        ; WaitBlit()
  158.        jsr     -456(a6)         ; OwnBlitter()
  159.     move.w    #0,$dff01fc        ; Reset AGA sprites
  160.     move.w    #0,$dff0106        ; 
  161.  
  162.     ; Kill multitasking ---------------------------------------------------
  163.  
  164.     move.l    $4.w,a6            ;
  165.     jsr    -132(a6)        ; Forbid()
  166.     
  167.     ; Get VBR -------------------------------------------------------------
  168.  
  169.        move.l     $4.w,a6            ; Switch to supervisor mode, because
  170.        lea     .get(pc),a5        ; movec is a privileged instruction.
  171.        jsr     -$1e(a6)          ; Supervisor()
  172.        bra.b     .store            ;
  173. .get     movec    vbr,d0            ; (dc.l $4e7a0801)
  174.        rte                ;
  175. .store     move.l     d0,_vbr            ; Store VBR
  176.  
  177.     ; Int3 Vector ---------------------------------------------------------
  178.  
  179.     move.w    $dff002,d0        ; Save DMACON
  180.     ori.w    #$8000,d0        ;
  181.     move.w    d0,olddmacon        ;
  182.     move.w    $dff01c,d0        ; Save INTENA
  183.     ori.w    #$c000,d0        ;
  184.     move.w    d0,oldintena        ;
  185.  
  186.     move.w    #$7fff,$dff09a        ; Kill interrupts
  187.     move.w    #$7fff,$dff09c        ; 
  188.     move.w    #$7fff,$dff096        ; Kill DMA
  189.     
  190.        move.l     _vbr,a0            ;
  191.        move.l     $6c(a0),oldint3        ; Store old Int3 vector
  192.  
  193.  
  194. ; *****************************************************************************
  195. ; Main 
  196. ; *****************************************************************************
  197.  
  198.        jsr Main
  199.  
  200. ; *****************************************************************************
  201. ; Done 
  202. ; *****************************************************************************
  203.  
  204. Done    ; Restore interrupt vectors -------------------------------------------
  205.  
  206.     move.w    #$7fff,$dff09a        ; Kill interrupts
  207.     move.w    #$7fff,$dff09c        ;
  208.     move.w    #$7fff,$dff096        ; Kill DMA
  209.     
  210.        move.l     _vbr,a0            ;
  211.        move.l     oldint3,$6c(a0)        ;
  212.  
  213.     move.w    olddmacon,$dff096    ; Restore DMACON
  214.     move.w    oldintena,$dff09a    ; Restore INTENA
  215.  
  216.     ; Enable multitasking -------------------------------------------------
  217.     
  218.     move.l    $4.w,a6            ;
  219.     jsr    -138(a6)        ; Permit()
  220.  
  221.     ; Restore screen ------------------------------------------------------
  222.     
  223.        move.l     gfxbase,a6        ;
  224.        move.l     oldview,a1        ;
  225.        jsr     -222(a6)         ; LoadView(oldview)
  226.        jsr     -462(a6)         ; DisownBlitter()
  227.  
  228.        move.l     $26(a6),$dff080       ; gb_copinit
  229.        move.l    #0,$dff088        ;
  230.  
  231.     ; Open Workbench ------------------------------------------------------
  232.  
  233.     IFEQ    ASMOne            ;
  234.     tst.l    wbclosed        ; IF Workbench was closed 
  235.     beq.b    .wbopen            ;
  236.     move.l    intuibase,a6        ;
  237.     jsr    -210(a6)        ;   OpenWorkBench()
  238. .wbopen                    ; ENDIF
  239.     ENDC                ;
  240.     
  241.     ; Free memory and close libraries -------------------------------------
  242.     
  243.        move.l    $4.w,a6            ;
  244.        move.l     fastmem,a1        ;
  245.        move.l     #fast+8192,d0        ;
  246.        jsr     -210(a6)        ; FreeMem()
  247. nofast
  248.        move.l    $4.w,a6            ;
  249.        move.l     chipmem,a1        ;
  250.        move.l     #chip+65536,d0        ;    
  251.        jsr     -210(a6)        ; FreeMem()
  252. nochip
  253. noaga
  254.        move.l     4,a6            ;
  255.     move.l    dosbase,a1        ;
  256.     jsr    -414(a6)         ; CloseLibrary()
  257. nodos
  258.     move.l    4,a6            ;
  259.        move.l     gfxbase,a1        ;
  260.        jsr     -414(a6)         ; CloseLibrary()
  261. nogfx
  262.        move.l     4,a6            ;
  263.        move.l     intuibase,a1        ;
  264.        jsr     -414(a6)         ; CloseLibrary()
  265. nointui
  266.     move.l    ReturnCode,d0        ; 
  267.        rts
  268.  
  269.  
  270. ; *****************************************************************************
  271. ; Data 
  272. ; *****************************************************************************
  273.  
  274.     ALIGNLONG
  275.  
  276. ReturnMsg    dc.l    0        ; Workbench message
  277. ReturnCode    dc.l    0        ; CLI return code
  278.         
  279. _vbr         dc.l     0        ; VBR address
  280.  
  281. oldint3        dc.l     0        ; Old Int3 vector
  282. oldview     dc.l     0        ; Old view
  283.  
  284. olddmacon    dc.w     0        ; Old DMACON
  285. oldintena    dc.w     0        ; Old INTENA
  286.  
  287. chipmem     dc.l     0        ; Amount of required chipmem
  288. fastmem     dc.l     0        ; Amount of required fastmem
  289.  
  290. dosbase        dc.l     0        ; DOSBase
  291. gfxbase     dc.l     0        ; GFXBase
  292. intuibase     dc.l     0        ; IntuiBase
  293.  
  294. wbclosed    dc.l    0        ; 0 = Unable to close Workbench
  295.  
  296. dosname        dc.b     "dos.library",0
  297. grafname     dc.b     "graphics.library",0
  298. intname     dc.b     "intuition.library",0
  299.  
  300.  
  301. ; =============================================================================
  302. ;                             M A I N   P R O G R A M
  303. ;
  304. ; =============================================================================
  305.  
  306. ; *****************************************************************************
  307. ; Macros
  308. ; *****************************************************************************
  309.  
  310. PPUTSTR    MACRO                ; PPUTSTR StringPtr,PlanarBufferOffset
  311.     movem.l    d0-d7/a0-a6,-(sp)    ;
  312.     move.l    \1,a0            ;
  313.     move.l    chipmem,a1        ;
  314.     add.l    #scr0,a1        ;
  315.     add.l    \2,a1            ;
  316.     bsr    PPutStr            ;
  317.     movem.l    (sp)+,d0-d7/a0-a6    ;
  318.     ENDM                ;
  319.  
  320. PPUTCHR    MACRO                ; PPUTCHR Character,PlanarBufferOffset
  321.     movem.l    d0-d7/a0-a6,-(sp)    ;
  322.     moveq    #0,d0            ;
  323.     move.l    \1,d0            ;
  324.     move.l    chipmem,a1        ;
  325.     add.l    #scr0,a1        ;
  326.     add.l    \2,a1            ;
  327.     bsr    PPutChr            ;
  328.     movem.l    (sp)+,d0-d7/a0-a6    ;
  329.     ENDM                ;
  330.  
  331. PPUTNUM    MACRO                ; PPUTNUM Number,PlanarBufferOffset
  332.     movem.l    d0-d7/a0-a6,-(sp)    ;
  333.     move.l    \1,d0            ;
  334.     add.l    #48,d0            ;
  335.     move.l    chipmem,a1        ;
  336.     add.l    #scr0,a1        ;
  337.     add.l    \2,a1            ;
  338.     bsr    PPutChr            ;
  339.     movem.l    (sp)+,d0-d7/a0-a6    ;
  340.     ENDM
  341.     
  342. CPUTSTR    MACRO                ; CPUTSTR StringPtr,ChunkyBufferOffset
  343.     movem.l    d0-d7/a0-a6,-(sp)    ;
  344.     lea    \1,a0            ;
  345.     move.l    RendCh,a1        ;
  346.     add.l    \2,a1            ;
  347.     bsr    CPutStr            ;
  348.     movem.l    (sp)+,d0-d7/a0-a6    ;
  349.     ENDM                ;
  350.  
  351. CPUTCHR    MACRO                ; CPUTCHR Character,ChunkyBufferOffset
  352.     movem.l    d0-d7/a0-a6,-(sp)    ;
  353.     moveq    #0,d0            ;
  354.     move.l    \1,d0            ;
  355.     move.l    RendCh,a1        ;
  356.     add.l    \2,a1            ;
  357.     bsr    CPutChr            ;
  358.     movem.l    (sp)+,d0-d7/a0-a6    ;
  359.     ENDM                ;
  360.  
  361. CPUTNUM    MACRO                ; CPUTNUM Number,ChunkyBufferOffset
  362.     movem.l    d0-d7/a0-a6,-(sp)    ;
  363.     moveq    #0,d0            ;
  364.     move.l    \1,d0            ;
  365.     add.l    #48,d0            ; Convert Number to ASCII
  366.     move.l    RendCh,a1        ;
  367.     add.l    \2,a1            ;
  368.     bsr    CPutChr            ;
  369.     movem.l    (sp)+,d0-d7/a0-a6    ;
  370.     ENDM                ;
  371.  
  372.  
  373. ; *****************************************************************************
  374. ; Memory 
  375. ; *****************************************************************************
  376.  
  377.     CLRMEM                ;
  378.     ADDMEM    shit,8            ; If I leave this bit out, then the
  379.                     ; cop0 copperlist gets totally fucked 
  380.                     ; up. This is related to mt_init. Why ?
  381.     
  382.     ADDMEM     cop0,8192        ; Copperlists
  383.     ADDMEM    cop1,8192        ;
  384.     
  385.           ADDMEM     ch0,160*128        ; Chunky buffers 
  386.        ADDMEM    ch1,160*128        ;
  387.        ADDMEM     scr0,320*128        ; Screens    
  388.        ADDMEM    scr1,320*128        ;
  389.     
  390.        ADDMEM     buf2,160*128*2        ; Pass-buffer   (160*128/2 ???)
  391.        ADDMEM     sblbuf,160*128        ; Scramble-buffer 
  392.        ADDMEM     sprbuf,(312*8*2)*8    ; Sprite buffer  
  393.           ADDMEM     chipend,1        ;
  394. chip     equ chipend              ; Amount of required chipmem
  395.  
  396.        CLRMEM                ;
  397.        ADDMEM     blist0,40*1024         ; Blitlist buffers
  398.         ADDMEM    blist1,40*1024        ;
  399.        ADDMEM     fastend,1        ;
  400. fast     equ fastend            ; Amount of required fastmem
  401.  
  402.  
  403. ; *****************************************************************************
  404. ; Raw key codes
  405. ; *****************************************************************************
  406.  
  407. KEY_NONE    = $00            ; No key pressed
  408. KEY_NEW        = $01            ; New key pressed
  409. KEY_REPEAT    = $02            ; Key repeated
  410.  
  411. KEY_F1          = $50        
  412. KEY_F2          = $51
  413. KEY_F3          = $52
  414. KEY_F4          = $53
  415. KEY_F5          = $54
  416. KEY_F6          = $55
  417. KEY_F7          = $56
  418. KEY_F8          = $57
  419. KEY_F9          = $58
  420. KEY_F10         = $59
  421.  
  422. KEY_Q           = $10
  423. KEY_W           = $11
  424. KEY_E           = $12
  425. KEY_R           = $13
  426. KEY_T           = $14
  427. KEY_Y           = $15
  428. KEY_U           = $16
  429. KEY_I           = $17
  430. KEY_O           = $18
  431. KEY_P           = $19
  432. KEY_A           = $20
  433. KEY_S           = $21
  434. KEY_D           = $22
  435. KEY_F           = $23
  436. KEY_G           = $24
  437. KEY_H           = $25
  438. KEY_J           = $26
  439. KEY_K           = $27
  440. KEY_L           = $28
  441. KEY_Z           = $31
  442. KEY_X           = $32
  443. KEY_C           = $33
  444. KEY_V           = $34
  445. KEY_B           = $35
  446. KEY_N           = $36
  447. KEY_M           = $37
  448.  
  449. KEY_ESC         = $45
  450. KEY_ENTER       = $44
  451. KEY_SPACE       = $40
  452. KEY_BACKSPACE    = $41
  453.  
  454.  
  455. ; *****************************************************************************
  456. ; Types
  457. ; *****************************************************************************
  458.  
  459. Type_HoleX1    equ    0        ; }_ TopLeft-coordinates of hole
  460. Type_HoleY1    equ    2        ; }
  461. Type_HoleX2    equ    4        ; }_ BottomRight-coordinates of hole
  462. Type_HoleY2    equ    6        ; }
  463.  
  464. Level_sizeof    equ    8        ;
  465. Level_NumWall    equ    0        ; Total number of walls
  466. Level_Ships    equ    2        ; Number of ships
  467. Level_Time    equ    4        ; Time (in ticks)
  468.  
  469. Coll_BoundsX1    equ    0        ; }_ TopLeft-coordinates of 
  470. Coll_BoundsY1    equ    2        ; }  collision boundary
  471. Coll_BoundsX2    equ    4        ; }_ BottomRight-coordinates of
  472. Coll_BoundsY2    equ    6        ; }  collision boundary
  473.  
  474.  
  475. ; *****************************************************************************
  476. ; Constants
  477. ; *****************************************************************************
  478.  
  479. TRUE        = 1            ; }_ Boolean values
  480. FALSE        = 0            ; }
  481.  
  482. BufferW        = 160            ; }_ Chunky buffer dimensions
  483. BufferH        = 128            ; }
  484.  
  485. ClipL        = 0            ; }
  486. ClipR        = BufferW-1        ; }_ Clipping borders
  487. ClipT        = 0            ; }
  488. ClipB        = BufferH-1        ; } 
  489.  
  490. CenterX        = BufferW/2        ; }_ Center of chunky buffer
  491. CenterY        = BufferH/2        ; }
  492.  
  493. ViewD        = 256*32*2/8        ; Maximum visible depth
  494. RealZ        = 200            ; Adjust player Z-coordinate
  495.  
  496. MinSpd        = 0            ; Minimum speed
  497. MaxSpd        = 25600            ; Maximum speed
  498.  
  499. Plyr_XInit    = 80            ; }_ Initial player coordinates
  500. Plyr_YInit    = 75            ; }
  501.  
  502. Plyr_XMin    = 32            ; }
  503. Plyr_XMax    = BufferW-32        ; }_ Min/Max. player coordinates
  504. Plyr_YMin    = 32            ; }
  505. Plyr_YMax    = BufferH-32        ; }
  506.  
  507. XAccel        = 1            ; }
  508. YAccel        = 1            ; }- Acceleration
  509. ZAccel        = 256            ; }
  510.  
  511. NumLevel    = 5            ; Number of levels
  512. MaxWall        = 128            ; Max. number of walls per level
  513.  
  514. Flg_Normal    = 0            ; Game-loop status flags
  515. Flg_Collision    = 1            ;   Hit a wall
  516. Flg_LevelDone    = 2            ;   Flying away from level
  517. Flg_LevelInit    = 3            ;   Flying to new level
  518. Flg_GetReady    = 4            ;   Ready to start new level
  519. Flg_NewShip    = 5            ;   Ready to start new life
  520. Flg_OutOfTime    = 6            ;   No time left
  521. Flg_RaceOver    = 7            ;   Crashed too many times
  522. Flg_Pause    = 8             ;   Pause mode
  523. Flg_Quit    = 99            ;   Leaving game-loop
  524.  
  525. WT_Start    = 0            ; Wall types
  526. WT_Finish    = 1            ;
  527. WT_Left        = 2            ;
  528. WT_Right    = 3            ;
  529. WT_Up        = 4            ;
  530. WT_Down        = 5            ;
  531.  
  532. IFlg_Text    = 0            ; Show intro-text
  533. IFlg_AskName    = 1            ; User enters name
  534. IFlg_TrackSel    = 2            ; Track select
  535. IFlg_Quit    = 99            ; Leaving intro-loop
  536. IFlg_QuitToWB    = 100            ; Leaving intro-loop and exit to WB
  537.  
  538. MaxStrLen    = 11            ; Max. length of input string
  539.  
  540.  
  541. ; *****************************************************************************
  542. ; Code
  543. ; *****************************************************************************
  544.  
  545.     ALIGNLONG
  546.     
  547. Main    bsr.b    InitMain            ; Initialisation
  548.  
  549. .Intro    bsr.w    Intro                ; Do intro
  550.     cmp.l    #IFlg_QuitToWB,Intro_Flags    ; IF player pressed ESC ?
  551.     beq.b    .Done                ; THEN exit
  552.         
  553.     bsr.w    InitLevel            ;
  554.     bsr.w    GameLoop            ;
  555.     bra.b    .Intro                ;
  556. .Done    
  557.     bsr.w    DoneMain            ; Clean up
  558.     rts                    ;
  559.  
  560.  
  561. ; =============================================================================
  562. ;
  563. ;                           G A M E   R O U T I N E S
  564. ;
  565. ; =============================================================================
  566.  
  567. ; *****************************************************************************
  568. ; InitMain
  569. ; -----------------------------------------------------------------------------
  570. ; Inputs     : -
  571. ; Output     : -
  572. ; Description: First initialisation.
  573. ; Notes      : -
  574. ; Scratch    : -
  575. ; Author     : -
  576. ; History    : -
  577. ; *****************************************************************************
  578.  
  579. InitMain
  580.     ; Copy bitplane pointers to intro copperlist --------------------------
  581.     
  582.     lea    IntroCopBpl,a2        ; a2=Position in copperlist header
  583.     move.l    #IntroPic,d0        ; d0=Screen address
  584.        move.w     #6-1,d7            ; Write 6 bitplanes
  585. .mkbpl    swap    d0            ;
  586.     move.w    d0,2(a2)        ; Write MSW
  587.     swap    d0            ;
  588.     move.w    d0,6(a2)        ; Write LSW
  589.     addq.l    #8,a2            ; Next position in copperlist
  590.     add.l    #320*256/8,d0        ; Next bitplane
  591.     dbf    d7,.mkbpl        ;
  592.  
  593.     ; Copy sprite pointers to intro copperlist ----------------------------
  594.  
  595.     lea    IntroCopSpr,a2        ; a2=Position in copperlist header
  596.     move.l    #SpriteData,d0        ; d0=Address of sprite data
  597.        move.w     #8-1,d7            ; Write 8 sprites
  598. .mkspr    swap    d0            ;
  599.     move.w    d0,2(a2)        ; Write MSW
  600.     swap    d0            ;
  601.     move.w    d0,6(a2)        ; Write LSW
  602.     addq.l    #8,a2            ; Next position in copperlist
  603.     dbf    d7,.mkspr        ;
  604.     
  605.     ; Make BlitterScreen copperlists --------------------------------------
  606.  
  607.     move.l    chipmem,a0        ; 
  608.     add.l    #cop0,a0        ; a0=Copperlist 0
  609.        move.l     chipmem,a1        ;
  610.      add.l     #scr0,a1        ; a1=Screen 0
  611.        bsr.w     mkbltscr                ; Create copperlist
  612.  
  613.     move.l    chipmem,a0        ;
  614.     add.l    #cop1,a0        ; a0=Copperlist 1
  615.        move.l     chipmem,a1        ;
  616.      add.l     #scr1,a1        ; a1=Screen 1
  617.        bsr.w     mkbltscr                ; Create copperlist
  618.  
  619.     ; Init double buffering pointers --------------------------------------
  620.  
  621.     move.l    fastmem,RendBL        ;
  622.     add.l    #blist0,RendBL        ;
  623.     move.l    fastmem,DispBL        ;
  624.     add.l    #blist1,DispBL        ;
  625.  
  626.     move.l    chipmem,RendCh        ;
  627.     add.l    #ch0,RendCh        ;
  628.     move.l    chipmem,DispCh        ;
  629.     add.l    #ch1,DispCh        ;
  630.  
  631.     move.l    chipmem,RendCop        ;
  632.     add.l    #cop0,RendCop        ;
  633.     move.l    chipmem,DispCop        ;
  634.     add.l    #cop1,DispCop        ;
  635.  
  636.     ; Other stuff ---------------------------------------------------------
  637.     
  638.     bsr.w    LoadScores        ; Init Hall of Fame
  639.     bsr.w    SetCIAInt        ; Set music player interrupt
  640.     move.l    #IFlg_Text,Intro_Flags    ; Start intro at part I
  641.         
  642.     ; Finished ------------------------------------------------------------
  643.     
  644.     rts
  645.  
  646.  
  647. ; *****************************************************************************
  648. ; DoneMain
  649. ; -----------------------------------------------------------------------------
  650. ; Inputs     : -
  651. ; Output     : -
  652. ; Description: Cleans up the mess.
  653. ; Notes      : -
  654. ; Scratch    : -
  655. ; Author     : -
  656. ; History    : -
  657. ; *****************************************************************************
  658.  
  659. DoneMain
  660.     bsr.w    ResetCIAInt        ; Remove music player interrupt
  661.     rts
  662.  
  663.  
  664. ; *****************************************************************************
  665. ; Intro 
  666. ; -----------------------------------------------------------------------------
  667. ; Inputs     : -
  668. ; Output     : -
  669. ; Description: -
  670. ; Notes      : -
  671. ; Scratch    : All
  672. ; Author     : -
  673. ; History    : -
  674. ; *****************************************************************************
  675.  
  676.     ALIGNLONG
  677.     
  678. Intro
  679.     ; Everything off ------------------------------------------------------
  680.  
  681.     move.w    #$7fff,$dff09a            ; Kill interrupts
  682.     move.w    #$7fff,$dff09c            ;
  683.     move.w    #$7fff,$dff096            ; Kill DMA
  684.  
  685.     ; Set palette ---------------------------------------------------------
  686.     
  687.     move.l    #IntroCopCol,a0            ; Set palette
  688.     move.l    #IntroPal,a1            ;
  689.     bsr.w    SetPal24            ;
  690.     move.l    #IntroCop,$dff080        ; Display copperlist
  691.  
  692.     ; Init planes 7 and 8 -------------------------------------------------
  693.  
  694.     lea    IntroCopBpl,a2            ; a2=Position in copperlist
  695.     add.l    #8*6,a2                ;
  696.     move.l    chipmem,d0            ; Write last two bitplanes
  697.     add.l    #scr0,d0            ; Plane 7
  698.     swap    d0                ;
  699.     move.w    d0,2(a2)            ; 
  700.     swap    d0                ;
  701.     move.w    d0,6(a2)            ;
  702.     addq.l    #8,a2                ;
  703.     add.l    #20480,d0            ; Plane 8
  704.     swap    d0                ;
  705.     move.w    d0,2(a2)            ;
  706.     swap    d0                ;
  707.     move.w    d0,6(a2)             ;
  708.  
  709.     bsr.w    ClearPlanes            ; Clear planes 7 and 8
  710.     
  711.     ; Init stuff ----------------------------------------------------------
  712.  
  713.     move.b    #FALSE,Intro_WarpIn        ;
  714.     move.b    #FALSE,Intro_WarpOut        ;    
  715.     move.w    #0,Intro_WarpCount        ; Reset warp-counter
  716.     move.l    #-1,Intro_Timer            ; Reset timer
  717.     
  718.     move.w    Plyr_Level,Intro_Level        ; Intro_Level = Plyr_Level
  719.  
  720.     move.w    #$e000,$dff09a            ; Enable CIA interrupts
  721.     move.w    #$83af,$dff096            ; Enable BPL+COP+AUDx DMA
  722.  
  723.     ; Start music ---------------------------------------------------------
  724.     
  725.     move.l    #IntroMusic,mt_data        ; 
  726.     bsr.w    mt_init                ;
  727.     st    mt_Enable            ;
  728.     
  729. IntroLoop
  730.     ; Sync display --------------------------------------------------------
  731.  
  732.     bsr.w    WaitVBL                ; Wait for vertical blank
  733.     add.l    #1,Intro_Timer            ; Update timer
  734.  
  735.     ; WarpIn --------------------------------------------------------------
  736.  
  737. .WrpIn    cmp.b    #TRUE,Intro_WarpIn        ; WarpIn two last bitplanes
  738.     bne.b    .WrpOut                ; 
  739.  
  740.     add.w    #1,Intro_WarpCount        ; Intro_WarpCount += 1
  741.     bsr.w    Warp                ; Do warp effect
  742.     cmp.w    #31,Intro_WarpCount        ; IF Intro_WarpCount >= 31
  743.     blt.b    IntroText            ;   Intro_WarpIn=FALSE
  744.     move.b    #FALSE,Intro_WarpIn        ; ENDIF
  745.  
  746.     ; WarpOut -------------------------------------------------------------
  747.  
  748. .WrpOut    cmp.b    #TRUE,Intro_WarpOut        ; WarpOut two last bitplanes
  749.     bne.b    IntroText            ;
  750.  
  751.     sub.w    #1,Intro_WarpCount        ; Intro_WarpCount -= 1
  752.     bsr.w    Warp                ; Do warp effect
  753.     cmp.w    #0,Intro_WarpCount        ; IF Intro_WarpCount <= 0
  754.     bgt.b    IntroText            ;   Intro_WarpOut=FALSE
  755.     move.b    #FALSE,Intro_WarpOut        ; ENDIF
  756.  
  757.     ; Part I: Write text ==================================================
  758.  
  759. IntroText    
  760.     cmp.l    #IFlg_Text,Intro_Flags        ;
  761.     bne.w    IntroAskName            ;
  762.     
  763.     cmp.l    #0,Intro_Timer            ; CREDITS
  764.     bne.w    .1                ;
  765.     bsr.w    ClearPlanes            ;
  766.     move.b    #TRUE,Intro_WarpIn        ;
  767.     PPUTSTR #itxt_1,#40*280+20        ;
  768.     PPUTSTR    #itxt_0,#40*296+20        ;
  769.     PPUTSTR #itxt_1,#40*312+20        ;
  770.     PPUTSTR #itxt_2,#40*360+20        ;
  771.     PPUTSTR    #itxt_3,#40*376+20        ;
  772.     PPUTSTR    #itxt_4,#40*392+20        ;
  773.     PPUTSTR #itxt_5,#40*424+20        ;
  774.     PPUTSTR #itxt_6,#40*440+20        ;
  775.     PPUTSTR #itxt_7,#40*456+20        ;
  776.     PPUTSTR #itxt_8,#40*472+20        ;
  777.     
  778. .1    cmp.l    #150,Intro_Timer        ;
  779.     bne.b    .2                ;
  780.     move.b    #TRUE,Intro_WarpOut        ;
  781.     
  782. .2    cmp.l    #200,Intro_Timer        ; MORE CREDITS
  783.     bne.w    .3                ;
  784.     bsr.w    ClearPlanes            ;
  785.     move.b    #TRUE,Intro_WarpIn        ;
  786.     PPUTSTR    #itxt_19,#40*296+20        ;
  787.     PPUTSTR    #itxt_10,#40*288+20        ;
  788.     PPUTSTR    #itxt_11,#40*312+20        ;
  789.     PPUTSTR    #itxt_19,#40*368+20        ;
  790.     PPUTSTR    #itxt_12,#40*360+20        ;
  791.     PPUTSTR    #itxt_13,#40*384+20        ;
  792.     PPUTSTR    #itxt_19,#40*440+20        ;
  793.     PPUTSTR    #itxt_14,#40*432+20        ;
  794.     PPUTSTR    #itxt_15,#40*456+20        ;
  795.  
  796. .3    cmp.l    #350,Intro_Timer        ;
  797.     bne.b    .4                ;
  798.     move.b    #TRUE,Intro_WarpOut        ;
  799.         
  800. .4    cmp.l    #400,Intro_Timer        ; HALL OF FAME
  801.     bne.w    .5                ;
  802.     bsr.w    ClearPlanes            ;
  803.     move.b    #TRUE,Intro_WarpIn        ;
  804.     PPUTSTR    #itxt_20,#40*272+20        ; }
  805.     PPUTSTR    #itxt_21,#40*288+20        ; }- Write Hall of Fame header
  806.     PPUTSTR    #itxt_22,#40*304+20        ; }
  807.     lea    BestTimes,a0            ; a0 = Pointer to BestTimes
  808.     lea    BestNames,a1            ; a1 = Pointer to BestNames
  809.     move.w    #NumLevel-1,d7            ; d7 = Loop counter
  810.     move.l    #0,d1                ; d1 = Level counter
  811.     move.l    #40*336+21,d2            ; d2 = Screen position
  812. .4loop    move.l    d1,d0                ; d0 = levelnr
  813.     addq.l    #1,d0                ; Adjust levelnr
  814.     PPUTNUM    d0,d2                ; Write track number
  815.     move.l    d1,d0                ; d0 = levelnr
  816.     mulu.w    #12,d0                ;
  817.     move.l    a1,a2                ; a2 = Pointer to BestNames
  818.     add.l    d0,a2                ; a2 += levelnr*12
  819.     move.l    d2,a4                ;
  820.     add.l    #2,a4                ;
  821.     PPUTSTR    a2,a4                ; Write BestName
  822.     move.l    d1,d0                ; d0 = levelnr
  823.     move.l    (a0,d0.w*4),d5            ; d5 = Time
  824.     move.l    d2,a4                ;
  825.     add.l    #14,a4                ;
  826.     bsr.w    PWriteTime            ; Write BestTime
  827.     addq.l    #1,d1                ; Increase level counter
  828.     add.l    #40*16,d2            ; Increase screen position
  829.     dbf    d7,.4loop            ;
  830.  
  831. .5    cmp.l    #550,Intro_Timer        ;
  832.     bne.b    .0                ;
  833.     move.b    #TRUE,Intro_WarpOut        ;
  834.  
  835. .0    cmp.l    #600,Intro_Timer        ;
  836.     bne.b    .input                ;
  837.     move.l    #-1,Intro_Timer            ; Reset intro timer
  838.  
  839.     ; Get input -----------------------------------------------------------
  840. .input
  841.     bsr.w    GetJoy1                ; IF Joy1Fire
  842.     tst.b    Joy1Fire            ;
  843.     beq.b    .keys                ; 
  844.     move.l    #IFlg_AskName,Intro_Flags    ;   Intro_Flags=IFlg_AskName 
  845.     move.b    #FALSE,Intro_WarpIn        ;   Stop warp-in
  846.     move.b    #TRUE,Intro_WarpOut        ;   Start warp-out
  847.     move.l    #-1,Intro_Timer            ;   Reset timer
  848.     bra.w    IntroQuit            ; ENDIF
  849. .keys
  850.     bsr.w    GetKey                ; IF ESC-key pressed
  851.     cmp.b    #KEY_NEW,KeyState        ;
  852.     bne.w    IntroQuit            ;
  853.     cmp.b    #KEY_ESC,KeyRaw            ;
  854.      bne.w    IntroQuit            ;
  855.     move.l    #IFlg_QuitToWB,Intro_Flags    ;   Intro_Flags=IFlg_QuitToWB
  856.     bra.w    IntroQuit            ; ENDIF
  857.  
  858.     ; Part II: Ask user name ==============================================
  859.  
  860. IntroAskName
  861.     cmp.l    #IFlg_AskName,Intro_Flags    ; 
  862.     bne.w    IntroTrackSel            ;
  863.     
  864.     cmp.l    #40,Intro_Timer            ; Wait for warp-out finished
  865.     blt.w    IntroQuit            ;
  866.     
  867.     cmp.l    #40,Intro_Timer            ;
  868.     bne.w    .0                ;
  869.     bsr.w    ClearPlanes            ; Erase planes 7 & 8
  870.     PPUTSTR #ian_0,#40*356+20        ;
  871.     PPUTSTR #ian_1,#40*372+20        ;
  872.     PPUTSTR #ian_2,#40*388+20        ;
  873.     PPUTSTR #ian_3,#40*404+20        ;
  874.     move.b    #TRUE,Intro_WarpIn        ; Start warp-in
  875.  
  876. .0    cmp.l    #80,Intro_Timer            ; Wait for warp-in finished
  877.     blt.w    IntroQuit            ;
  878.     bsr.w    GetStr                ; Read player name
  879.         
  880.     move.l    #IFlg_TrackSel,Intro_Flags    ; Go to part III
  881.     move.b    #FALSE,Intro_WarpIn        ; Stop warp-in 
  882.     move.b    #TRUE,Intro_WarpOut        ; Start warp-out
  883.     move.l    #-1,Intro_Timer            ; Reset timer
  884.     bra.w    IntroQuit            ; 
  885.  
  886.     ; Part III : Track Select =============================================
  887.     
  888. IntroTrackSel
  889.     cmp.l    #IFlg_TrackSel,Intro_Flags    ;
  890.     bne.w    IntroQuit            ;
  891.  
  892.     cmp.l    #40,Intro_Timer            ; Wait for warp-out finished
  893.     blt.w    IntroQuit            ;
  894.     
  895.     cmp.l    #40,Intro_Timer            ; WRITE TRACK INFO
  896.     bne.w    .input                ;
  897.     move.b    #TRUE,Intro_WarpIn        ; Start warp-in
  898.     bsr.w    ClearPlanes            ; Erase planes 7 & 8
  899.     PPUTSTR #its_0,#40*264+20        ; }
  900.     PPUTSTR    #its_1,#40*280+20        ; }- Header
  901.     PPUTSTR    #its_2,#40*296+20        ; }
  902.     PPUTSTR    #its_3,#40*320+20        ; TRACK
  903.     PPUTSTR    #its_4,#40*336+20        ; TIME
  904.     PPUTSTR    #its_5,#40*352+20        ; SHIPS
  905.     PPUTSTR    #its_6,#40*384+20        ; BEST 
  906.     PPUTSTR    #its_7,#40*424+20        ; }
  907.     PPUTSTR    #its_8,#40*440+20        ; }
  908.     PPUTSTR    #its_9,#40*456+20        ; }- Joystick info
  909.     PPUTSTR    #its_10,#40*472+20        ; }
  910.     PPUTSTR    #its_11,#40*488+20        ; }
  911.     moveq    #0,d0                ;
  912.     move.w    Intro_Level,d0            ; d0 = Current selected levelnr
  913.     move.l    d0,d2                ; 
  914.     move.l    d0,d1                ; 
  915.     addq.w    #1,d1                ; Adjust levelnr
  916.     PPUTNUM    d1,#40*320+34            ; Write Intro_Level
  917.     mulu.w    #Level_sizeof,d0        ;
  918.     lea    Level,a0            ;
  919.     move.w    Level_Ships(a0,d0.w),d1        ;
  920.     PPUTNUM    d1,#40*352+34            ; Write Level_Ships
  921.     move.l    Level_Time(a0,d0.w),d5        ;
  922.     move.l    #40*336+31,a4            ;
  923.     bsr.w    PWriteTime            ; Write Level_Time
  924.     lea    BestTimes,a0            ;
  925.     move.l    (a0,d2.w*4),d5            ;
  926.     move.l    #40*400+34,a4            ;
  927.     bsr.w    PWriteTime            ; Write BestTime
  928.     lea    BestNames,a1            ;
  929.     mulu.w    #12,d2                ;
  930.     add.l    d2,a1                ;
  931.     PPUTSTR    a1,#40*400+22            ; Write BestName
  932.  
  933.     ; Get input -----------------------------------------------------------
  934. .input
  935.     cmp.b    #FALSE,Intro_WarpOut        ; IF Warping-in 
  936.     bne.w    .keys                ; THEN skip joystick part
  937.     cmp.b    #FALSE,Intro_WarpIn        ; IF Warping-out
  938.     bne.w    .keys                ; THEN skip joystick part
  939.  
  940.     bsr.w    GetJoy1                ; IF Joy1Fire
  941.     tst.b    Joy1Fire            ;
  942.     beq.b    .nofire                ;
  943.     move.l    #IFlg_Quit,Intro_Flags        ;   Play selected level !
  944.     bra.w    IntroQuit            ; ENDIF
  945.  
  946. .nofire    tst.b    Joy1Left            ; IF Joy1Left
  947.     beq.b    .noleft                ; 
  948.     move.l    #-1,Intro_Timer            ;   Warp
  949.     move.b    #TRUE,Intro_WarpOut        ;
  950.     sub.w    #1,Intro_Level            ;   Intro_Level -= 1
  951.     bpl.w    IntroQuit            ;   IF Intro_Level < 0
  952.     move.w    #0,Intro_Level            ;   THEN Intro_Level = 0
  953.     move.l    #$7fff,Intro_Timer        ;
  954.     move.b    #FALSE,Intro_WarpOut        ;   Don't warp
  955.     bra.w    IntroQuit            ; ENDIF
  956.     
  957. .noleft    tst.b    Joy1Right            ; IF Joy1Right
  958.     beq.b    .keys                ;
  959.     move.l    #-1,Intro_Timer            ;   Warp
  960.     move.b    #TRUE,Intro_WarpOut        ;
  961.     add.w    #1,Intro_Level            ;   Intro_Level += 1
  962.     cmp.w    #NumLevel,Intro_Level        ;   IF Intro_Level = NumLevel
  963.     blt.b    IntroQuit            ;   THEN Intro_Level=NumLevel-1
  964.     sub.w    #1,Intro_Level            ;  
  965.     move.l    #$7fff,Intro_Timer        ;   Don't warp
  966.     move.b    #FALSE,Intro_WarpOut        ;
  967.     bra.b    IntroQuit            ; ENDIF
  968. .keys
  969.     bsr.w    GetKey                ; IF ESC-key pressed
  970.     cmp.b    #KEY_NEW,KeyState        ;
  971.     bne.b    IntroQuit            ;
  972.     cmp.b    #KEY_ESC,KeyRaw            ;
  973.      bne.b    IntroQuit            ;
  974.     move.l    #IFlg_Text,Intro_Flags        ;   Back to part I
  975.     move.b    #FALSE,Intro_WarpIn        ;   Stop warp-in 
  976.     move.b    #TRUE,Intro_WarpOut        ;   Start warp-out
  977.     move.l    #550,Intro_Timer        ;   Reset timer
  978.     bra.w    IntroQuit            ; ENDIF
  979.  
  980.     ; Quit ? ==============================================================
  981.  
  982. IntroQuit
  983.     IFNE     DEBUG                ;
  984.        btst     #2,$dff016            ; Check right mousebutton 
  985.     bne.b    .z                ;
  986.     move.l    #IFlg_QuitToWB,Intro_Flags    ;
  987. .z    ENDC                    ;
  988.  
  989.     cmp.l    #IFlg_Quit,Intro_Flags        ; Quit intro-loop ?
  990.     blt.w    IntroLoop            ;
  991.  
  992.     ; Finished ------------------------------------------------------------
  993.  
  994.     move.w    Intro_Level,Plyr_Level        ; Play this level
  995.  
  996.     bsr.w    mt_end                ; Stop music
  997.     
  998.     move.w    #$7fff,$dff09a            ; Kill interrupts
  999.     move.w    #$7fff,$dff09c            ;
  1000.     move.w    #$7fff,$dff096            ; Kill DMA
  1001.     rts
  1002.  
  1003.  
  1004. ; *****************************************************************************
  1005. ; ClearPlanes
  1006. ; -----------------------------------------------------------------------------
  1007. ; Inputs     : -
  1008. ; Output     : -
  1009. ; Description: Erase intro screen plane 7 and 8.
  1010. ; Notes      : -
  1011. ; Scratch    : -
  1012. ; Author     : -
  1013. ; History    : -
  1014. ; *****************************************************************************
  1015.  
  1016. ClearPlanes                    ;
  1017.     move.l    chipmem,a0            ; Use scr0 buffer for last two
  1018.     add.l    #scr0,a0            ; bitplanes.
  1019.     move.w    #320*128/4-1,d7            ; 
  1020.     moveq    #0,d0                ;
  1021. .clr1    move.l    d0,(a0)+            ;
  1022.     dbf    d7,.clr1            ;
  1023.     rts
  1024.  
  1025.  
  1026. ; *****************************************************************************
  1027. ; Warp
  1028. ; -----------------------------------------------------------------------------
  1029. ; Inputs     : -
  1030. ; Output     : -
  1031. ; Description: Do intro warp effect.
  1032. ; Notes      : -
  1033. ; Scratch    : All
  1034. ; Author     : -
  1035. ; History    : -
  1036. ; *****************************************************************************
  1037.  
  1038. Warp
  1039.     move.w    Intro_WarpCount,d1    ; d1 = Index in IntroWarp table
  1040.     lea    IntroWarp,a0        ; a0 = Pointer to IntroWarp table
  1041.     lea    IntroCopBpl+6*8,a2    ; a2 = Position in copperlist header
  1042.     move.l    chipmem,d0        ; 
  1043.     add.l    #scr0,d0        ; Plane 7
  1044.     add.l    (a0,d1.w*4),d0        ; Add warp offset
  1045.     swap    d0            ;
  1046.     move.w    d0,2(a2)        ; 
  1047.     swap    d0            ;
  1048.     move.w    d0,6(a2)        ;
  1049.     addq.l    #8,a2            ;
  1050.     add.l    #20480,d0        ; Plane 8
  1051.     swap    d0            ;
  1052.     move.w    d0,2(a2)        ;
  1053.     swap    d0            ;
  1054.     move.w    d0,6(a2)         ;
  1055.     rts
  1056.  
  1057.  
  1058. ; *****************************************************************************
  1059. ; InitLevel 
  1060. ; -----------------------------------------------------------------------------
  1061. ; Inputs     : -
  1062. ; Output     : -
  1063. ; Description: -
  1064. ; Notes      : -
  1065. ; Scratch    : -
  1066. ; Author     : -
  1067. ; History    : -
  1068. ; *****************************************************************************
  1069.  
  1070. InitLevel
  1071.     ; Clear chunky buffers and screens ------------------------------------
  1072.  
  1073.     move.l    chipmem,a0            ; Note: chunky buffers must be
  1074.     add.l    #ch0,a0                ; allocated after each other
  1075.     move.w    #2*160*128/4-1,d7        ; in memory.
  1076. .clr0    move.l    #0,(a0)+            ;
  1077.     dbf    d7,.clr0            ;
  1078.  
  1079.     move.l    chipmem,a0            ; Note: screen buffers must be
  1080.     add.l    #scr0,a0            ; allocated after each other
  1081.     move.w    #2*320*128/4-1,d7        ; in memory.
  1082. .clr1    move.l    #0,(a0)+            ;
  1083.     dbf    d7,.clr1            ;
  1084.  
  1085.     ; Set palette ---------------------------------------------------------
  1086.  
  1087.     move.l    RendCop,a0            ; Set colours to black
  1088.     add.l    #CopCol-Cop,a0            ;
  1089.     move.l    #GamePal,a1            ;    
  1090.     bsr.w    SetPal24            ;
  1091.     move.l    DispCop,a0            ;
  1092.     add.l    #CopCol-Cop,a0            ;
  1093.     move.l    #GamePal,a1            ;
  1094.     bsr.w    SetPal24            ;
  1095.     
  1096.     ; DMA & Interrupts ----------------------------------------------------
  1097.     
  1098.     move.w    #$7fff,$dff09a            ; Kill interrupts
  1099.     move.w    #$7fff,$dff09c            ;
  1100.     move.w    #$7fff,$dff096            ; Kill DMA
  1101.  
  1102.        move.l     _vbr,a0             ;
  1103.      move.l     #int3,$6c(a0)            ; INT3 vector
  1104.  
  1105.     move.l    DispCop,$dff080            ; Display copperlist
  1106.     
  1107.     move.w    #$e060,$dff09a            ; Enable BLIT+VERTB+CIA ints
  1108.        move.w     #$83cf,$dff096            ; Enable BPL+COP+BLT+AUD DMA
  1109.  
  1110.     ; Make BlitterScreen --------------------------------------------------
  1111.     
  1112.        move.l     chipmem,a0             ;
  1113.      add.l     #ch0,a0                  ; Chunky buffer
  1114.        move.l     chipmem,a1             ;
  1115.      add.l     #scr0,a1                 ; Planar screen
  1116.        move.l     chipmem,a2             ;
  1117.      add.l     #buf2,a2                 ; Pass buffer
  1118.        move.l     chipmem,a3             ;
  1119.      add.l     #sblbuf,a3               ; Scramble buffer
  1120.        move.l     fastmem,a6             ;
  1121.      add.l     #blist0,a6                ; Blitterlist buffer
  1122.  
  1123.        move.l     #160*128,d0                ; Number of chunky pixels
  1124.       move.l     #320*128/8,d1           ; Bytes between the bitplanes
  1125.  
  1126.       movem.l d0-d7/a0-a6,-(sp)        ;
  1127.        jsr     c2bs                         ; Make blitterlist 0
  1128.       movem.l (sp)+,d0-d7/a0-a6        ;
  1129.  
  1130.       move.l     chipmem,a0             ;
  1131.       add.l     #ch1,a0                  ; Chunky buffer
  1132.        move.l     chipmem,a1             ;
  1133.      add.l     #scr1,a1                 ; Planar screen
  1134.        move.l     chipmem,a2             ;
  1135.      add.l     #buf2,a2                 ; Pass buffer
  1136.        move.l     chipmem,a3             ;
  1137.      add.l     #sblbuf,a3               ; Scramble buffer
  1138.        move.l     fastmem,a6             ;
  1139.      add.l     #blist1,a6                ; Blitterlist buffer
  1140.  
  1141.        move.l     #160*128,d0                ; Number of chunky pixels
  1142.       move.l     #320*128/8,d1           ; Bytes between the bitplanes
  1143.  
  1144.       movem.l d0-d7/a0-a6,-(sp)        ;
  1145.        jsr     c2bs                         ; Make blitterlist 1 
  1146.       movem.l (sp)+,d0-d7/a0-a6        ;
  1147.  
  1148.     ; Start the music -----------------------------------------------------
  1149.  
  1150.     move.l    #GameMusic,mt_data        ;
  1151.     bsr.w    mt_init                ;
  1152.     st    mt_Enable            ;
  1153.  
  1154.     ; Init variables ------------------------------------------------------
  1155.  
  1156.     move.w    Plyr_Level,d1            ; d1 = Plyr_Level
  1157.     move.l    #Level,a0            ; Calculate Game_LevelPtr
  1158.     move.w    d1,d0                ;
  1159.     mulu    #Level_sizeof,d0        ;
  1160.     add.l    d0,a0                ;
  1161.     move.l    a0,Game_LevelPtr        ; 
  1162.     move.l    #Wall_Z,a0            ; Calculate Game_WallZ
  1163.     move.w    d1,d0                ;
  1164.     mulu    #MaxWall*4,d0            ;
  1165.     add.l    d0,a0                ;
  1166.     move.l    a0,Game_WallZ            ; 
  1167.     move.l    #Wall_Type,a0            ; Calculate Game_WallType
  1168.     move.w    d1,d0                ;
  1169.     mulu    #MaxWall*2,d0            ;
  1170.     add.l    d0,a0                ;
  1171.     move.l    a0,Game_WallType        ;
  1172.  
  1173.     move.w    #Plyr_XInit,Plyr_X        ; Init player position
  1174.     move.w    #Plyr_YInit,Plyr_Y        ;
  1175.     move.w    #0,Plyr_XSpd            ; Init player speed
  1176.     move.w    #0,Plyr_YSpd            ;
  1177.     move.w    #0,Plyr_Scroll            ;
  1178.     move.l    #0,Plyr_Z            ;
  1179.     move.w    #28*256,Plyr_ZSpd        ;
  1180.     
  1181.     move.w    #0,Plyr_Frame            ; Current frame number
  1182.     move.w    #7,Plyr_EngineCnt        ; Current engine colour
  1183.     move.w    #TRUE,Plyr_EngineOn        ; Engine is on...
  1184.  
  1185.     move.l    #Flg_LevelInit,Game_Flags    ; Init flags
  1186.     move.w    #0,Game_FirstWall        ; Init walls
  1187.     move.w    #0,Game_LastWall        ;
  1188.  
  1189.     lea    Plyr_Name,a0            ; IF Plyr_Name="MOTHERGOOSE"
  1190.     move.l    (a0)+,d0            ;
  1191.     cmp.l    #"MOTH",d0            ;
  1192.     bne.b    .nocht                ;
  1193.     move.l    (a0)+,d0            ;
  1194.     cmp.l    #"ERGO",d0            ;
  1195.     bne.b    .nocht                ;
  1196.     move.l    (a0)+,d0            ;
  1197.     cmp.l    #$4f534500,d0            ;
  1198.     bne.b    .nocht                ;
  1199.     move.w    #9,Plyr_Ships            ;   Plyr_Ships=9
  1200.     move.l    #29950,Plyr_Time        ;   Plyr_Time=9:59
  1201.     move.b    #TRUE,Plyr_Cheat        ;   Plyr_Cheat=TRUE
  1202.     bra.b    .Done                ; ELSE
  1203. .nocht    move.l    Game_LevelPtr,a0        ;   
  1204.     move.w    Level_Ships(a0),Plyr_Ships    ;   Plyr_Ships=Level_Ships
  1205.     move.l    Level_Time(a0),Plyr_Time    ;   Plyr_Time=Level_Time
  1206.     move.b    #FALSE,Plyr_Cheat        ;   Plyr_Cheat=FALSE
  1207.  
  1208.     ; Finished ------------------------------------------------------------
  1209. .Done    
  1210.     rts
  1211.     
  1212.  
  1213. ; *****************************************************************************
  1214. ; GameLoop
  1215. ; -----------------------------------------------------------------------------
  1216. ; Inputs     : -
  1217. ; Output     : -
  1218. ; Description: -
  1219. ; Notes      : -
  1220. ; Scratch    : -
  1221. ; Author     : -
  1222. ; History    : -
  1223. ; *****************************************************************************
  1224.  
  1225.     ALIGNLONG
  1226.     
  1227. GameLoop
  1228.         ; Sync display --------------------------------------------------------
  1229.  
  1230. .busy    tst.w   bltbsy                ; Wait for C2P finished
  1231.      bne.b     .busy                ; (bltbsy=0)
  1232.  
  1233.     bsr.w    WaitVBL                ; Wait for vertical blank
  1234.  
  1235.     move.l    RealTimeCnt,RealTime        ; Store realtime counter
  1236.     move.l    #0,RealTimeCnt            ; Reset realtime counter
  1237.  
  1238.     move.l    DispCop,$dff080            ; Display copperlist
  1239.  
  1240.     move.l    RendBL,d0            ; Do double buffering
  1241.     move.l    DispBL,RendBL            ;
  1242.     move.l    d0,DispBL            ;
  1243.     move.l    RendCh,d1            ;
  1244.     move.l    DispCh,RendCh            ;
  1245.     move.l    d1,DispCh            ;
  1246.     move.l    RendCop,d2            ;
  1247.     move.l    DispCop,RendCop            ;
  1248.     move.l    d2,DispCop            ;
  1249.  
  1250.         ; Start C2P -----------------------------------------------------------
  1251.  
  1252.     move.l    DispBL,bltpc            ; Blitterlist
  1253.        move.w     #1,bltbsy                ; Important!
  1254.        move.w     #$8040,$dff09c           ; Request blitter interrupt
  1255.  
  1256.     ; Render stuff --------------------------------------------------------
  1257.  
  1258.     bsr.w    DrawTunnel            ;
  1259.     bsr.w    DoWalls                ;
  1260.     bsr.w    DoPlayer            ;
  1261.     bsr.b    DoStatus            ;
  1262.  
  1263.     IFNE    SHOW                ;
  1264.     move.w    #$f00,$dff182            ; Show rastertiming
  1265.     ENDC                    ;
  1266.  
  1267.     ; Quit ? --------------------------------------------------------------
  1268.  
  1269.     cmp.l    #Flg_Quit,Game_Flags        ; Quit gameloop ?
  1270.        bne.w     GameLoop            ;
  1271.  
  1272. .c2pend    tst.w     bltbsy                 ; Make sure C2P is finished
  1273.      bne.b     .c2pend                ; before we continue
  1274.  
  1275.     ; Finished ------------------------------------------------------------
  1276. .Done
  1277.     bsr.w    mt_end                ; Stop music
  1278.     move.l    #IFlg_TrackSel,Intro_Flags    ; Restart intro at Track Select
  1279.        rts
  1280.  
  1281.  
  1282. ; *****************************************************************************
  1283. ; DoStatus
  1284. ; -----------------------------------------------------------------------------
  1285. ; Inputs     : -
  1286. ; Output     : -
  1287. ; Description: Draws status stuff in chunky buffer.
  1288. ; Notes      : -
  1289. ; Scratch    : -
  1290. ; Author     : -
  1291. ; History    : -
  1292. ; *****************************************************************************
  1293.  
  1294. DoStatus
  1295.     cmp.l    #Flg_LevelInit,Game_Flags    ; IF Game_Flags=Flg_LevelInit
  1296.     beq.b    .Done                ; THEN don't draw status
  1297.     cmp.l    #Flg_GetReady,Game_Flags    ; IF Game_Flags=Flg_GetReady
  1298.     beq.b    .Done                ; THEN don't draw status
  1299.     cmp.l    #Flg_LevelDone,Game_Flags    ; IF Game_Flags=Flg_LevelDone
  1300.     beq.b    .Done                ; THEN don't draw status
  1301.     
  1302.     ; Number of ships -----------------------------------------------------
  1303.  
  1304.     move.w    Plyr_Ships,d1            ;
  1305.     CPUTNUM    d1,#160+160-10            ;
  1306.  
  1307.     ; Time left -----------------------------------------------------------
  1308.  
  1309.     move.l    #160,a4                ;
  1310.     move.l    Plyr_Time,d5            ;
  1311.     bsr.w    CWriteTime            ;
  1312.     
  1313.     ; Finished ------------------------------------------------------------
  1314. .Done
  1315.     rts
  1316.     
  1317.     
  1318. ; *****************************************************************************
  1319. ; DoPlayer
  1320. ; -----------------------------------------------------------------------------
  1321. ; Inputs     : -
  1322. ; Output     : -
  1323. ; Description: Does player things.
  1324. ; Notes      : -
  1325. ; Scratch    : None
  1326. ; Author     : -
  1327. ; History    : -
  1328. ; *****************************************************************************
  1329.  
  1330.     ALIGNLONG
  1331.     
  1332. DoPlayer
  1333.     movem.l    d0-d7/a0-a6,-(sp)        ; Save regs
  1334.     
  1335.     ; Normal mode ---------------------------------------------------------
  1336.  
  1337.     cmp.l    #Flg_Normal,Game_Flags        ; Normal mode ?
  1338.     beq.w    .Player                ; 
  1339.  
  1340.     ; LevelInit -----------------------------------------------------------
  1341.  
  1342.     cmp.l    #Flg_LevelInit,Game_Flags    ; Level starts
  1343.     bne.b    .getrdy                ;
  1344.  
  1345.     sub.w    #ZAccel,Plyr_ZSpd        ; Plyr_ZSpd -= ZAccel
  1346.     cmp.w    #0,Plyr_ZSpd            ; IF Plyr_ZSpd < 0
  1347.     bge.w    .Keys                ;   
  1348.     move.w    #0,Plyr_ZSpd            ;   Plyr_ZSpd = 0
  1349.     move.l    #Flg_GetReady,Game_Flags    ;   Game_Flags=Flg_GetReady
  1350.     move.w    #FALSE,Plyr_EngineOn        ;   Stop Engine
  1351.     bra.w    .Keys                ; ENDIF
  1352.  
  1353.     ; GetReady ------------------------------------------------------------
  1354.  
  1355. .getrdy    cmp.l    #Flg_GetReady,Game_Flags    ; Waiting until player ready
  1356.     bne.w    .nwship                ;
  1357.  
  1358. .0    CPUTSTR    txt_track,#40+38*160        ; Write "TRACK"
  1359.     move.w    Plyr_Level,d1            ;
  1360.     add.w    #1,d1                ; +1 !!!
  1361.     CPUTNUM    d1,#112+38*160            ; Write Plyr_Level
  1362.  
  1363.     CPUTSTR    txt_time,#40+48*160        ; Write "TIME"
  1364.     move.l    #88+48*160,a4            ;
  1365.     move.l    Plyr_Time,d5            ;
  1366.     bsr.w    CWriteTime            ;
  1367.  
  1368.     CPUTSTR    txt_ships,#40+58*160        ; Write "SHIPS"
  1369.     move.w    Plyr_Ships,d1            ;
  1370.     CPUTNUM    d1,#112+58*160            ; Write Plyr_Ships
  1371.         
  1372.     tst.l    Toggle                ; IF Toggle-bit set
  1373.     beq.b    .gtrdy2                ;
  1374.     CPUTSTR    txt_press,#40+84*160        ; THEN Write "PRESS"
  1375.     CPUTSTR    txt_fire,#88+84*160        ;      Write "FIRE"
  1376.     
  1377. .gtrdy2    bsr.w    GetJoy1                ;
  1378.     tst.b    Joy1Fire            ; IF Fire-button
  1379.     beq.w    .Keys                ;
  1380.     move.l    #Flg_Normal,Game_Flags        ;   Game_Flags=Flg_Normal
  1381.     bra.w    .Keys                ; ENDIF
  1382.  
  1383.     ; NewShip -------------------------------------------------------------
  1384.  
  1385. .nwship    cmp.l    #Flg_NewShip,Game_Flags        ; Player has been resurrected
  1386.     bne.b    .ldone                ;
  1387.  
  1388.     tst.l    Toggle                ; IF Toggle-bit set
  1389.     beq.b    .nwshp2                ;
  1390.     CPUTSTR    txt_press,#40+84*160        ; THEN Write "PRESS"
  1391.     CPUTSTR txt_fire,#88+84*160        ;      Write "FIRE"
  1392.     
  1393. .nwshp2    bsr.w    GetJoy1                ;
  1394.     tst.b    Joy1Fire            ; IF Fire-button
  1395.     beq.w    .Keys                ;
  1396.     move.l    #Flg_Normal,Game_Flags        ;   Game_Flags=Flg_Normal
  1397.     bra.w    .Keys                ; ENDIF
  1398.  
  1399.     ; LevelDone -----------------------------------------------------------
  1400.     
  1401. .ldone    cmp.l    #Flg_LevelDone,Game_Flags    ; Level is completed
  1402.     bne.w    .coll                ;
  1403.  
  1404.     move.w    #0,Plyr_XSpd            ; No X/Y Speed
  1405.     move.w    #0,Plyr_YSpd            ;
  1406.     move.w    #TRUE,Plyr_EngineOn        ; Activate engine
  1407.     
  1408.     cmp.w    #28*256,Plyr_ZSpd        ; IF Plyr_ZSpd > xxxx
  1409.     blt.b    .lt                ;
  1410.     sub.w    #ZAccel,Plyr_ZSpd        ; THEN Plyr_ZSpd -= ZAccel
  1411.     bra.b    .ldone1                ;
  1412. .lt    add.w    #ZAccel,Plyr_ZSpd        ; ELSE Plyr_ZSpd += ZAccel
  1413.  
  1414. .ldone1    tst.l    Toggle                ; IF Toggle-bit set
  1415.     beq.w    .ldone3                ;
  1416.     CPUTSTR    txt_track,#24+60*160        ; THEN Write "TRACK"
  1417.     CPUTSTR    txt_complete,#72+60*160        ;      Write "COMPLETE"
  1418.  
  1419. .ldone2    move.l    Game_LevelPtr,a1        ; a1 = Pointer to Level array 
  1420.     cmp.b    #TRUE,Plyr_Cheat        ;
  1421.     bne.w    .ld0                ; IF Plyr_Cheat=TRUE
  1422.     move.l    #29950,d1            ; THEN d1 = 9:59
  1423.     bra.b    .ld1                ;
  1424. .ld0    move.l    Level_Time(a1),d1        ; ELSE d1 = Level_Time
  1425. .ld1    sub.l    Plyr_Time,d1            ; d1 = Level_Time - Plyr_Time
  1426.     lea    BestTimes,a2            ; a2 = Pointer to BestTimes
  1427.     move.w    Plyr_Level,d2            ; d2 = Plyr_Level
  1428.     move.l    (a2,d2.w*4),d3            ; d3 = BestTime for Plyr_Level
  1429.     cmp.l    d3,d1                ; IF d1 <= d3
  1430.     bgt.b    .ldone3                ;
  1431.     CPUTSTR    txt_best,#20+40*160        ; THEN Write "BEST" 
  1432.     CPUTSTR    txt_track,#56+40*160        ;      Write "TRACK"
  1433.     CPUTSTR    txt_time,#108+40*160        ;      Write "TIME"
  1434.     move.l    d1,(a2,d2.w*4)            ; Write time in BestTimes
  1435.     lea    BestNames,a2            ; a2 = Pointer to BestNames
  1436.     mulu.w    #12,d2                ; d2 = Offset in BestNames
  1437.     move.w    #12-1,d7            ;
  1438.     lea    Plyr_Name,a3            ; a3 = Pointer to player name
  1439. .lcopy    move.b    (a3)+,(a2,d2.w)            ; Copy character
  1440.     addq.w    #1,d2                ; Update dest. pointer
  1441.     dbf    d7,.lcopy            ;
  1442.  
  1443. .ldone3    cmp.l    #250,FlgTimer            ; IF FlgTimer = 5 secs
  1444.     ble.w    .Keys                ;
  1445.     move.l    #Flg_Quit,Game_Flags        ;   Game_Flags=Flg_Quit
  1446.     bra.w    .Keys                ; ENDIF
  1447.  
  1448.     ; Collision -----------------------------------------------------------
  1449.  
  1450. .coll    cmp.l    #Flg_Collision,Game_Flags    ; Collision with wall
  1451.     bne.w    .outtim                ;
  1452.  
  1453.     move.w    #Plyr_XInit,Plyr_X        ; Restore player stuff
  1454.     move.w    #Plyr_YInit,Plyr_Y        ;
  1455.     move.w    #0,Plyr_XSpd            ;
  1456.     move.w    #0,Plyr_YSpd            ;
  1457.     move.w    #0,Plyr_ZSpd            ;
  1458.     move.w    #0,Plyr_EngineCnt        ;
  1459.     move.w    #FALSE,Plyr_EngineOn        ;
  1460.  
  1461.     cmp.l    #50,FlgTimer            ; IF 0 <= FlgTimer < 50
  1462.     bge.b    .coll1                ;   Explosion handled by VBLint
  1463.     bra.w    .Keys                ; ENDIF
  1464.     
  1465. .coll1    tst.w    Plyr_Ships            ; IF Plyr_Ships = 0
  1466.     bne.b    .coll2                ;
  1467.     move.l    #Flg_RaceOver,Game_Flags    ;   Game_Flags=Flg_RaceOver
  1468.     bra.w    .Keys                ; ENDIF
  1469.  
  1470. .coll2    cmp.l    #100,FlgTimer            ; IF 50 <= FlgTimer < 100
  1471.     bge.b    .coll3                ;
  1472.     move.l    RealTime,d0            ;
  1473.      mulu.w    #10,d0                ;
  1474.     add.l    d0,Plyr_Z            ;   Move forward through tunnel
  1475.     move.l    RealTime,d0            ;   
  1476.      mulu.w    #2560,d0            ;
  1477.     add.w    d0,Plyr_Scroll            ;   until wall has disappeared
  1478.     bra.w    .Keys                ; ENDIF
  1479.         
  1480. .coll3    move.l    #Flg_NewShip,Game_Flags        ; IF FlgTimer = 100
  1481.     bra.w    .Keys                ; THEN Game_Flags=Flg_NewShip
  1482.  
  1483.     ; OutOfTime -----------------------------------------------------------
  1484.  
  1485. .outtim    cmp.l    #Flg_OutOfTime,Game_Flags    ; No time left
  1486.     bne.w    .racovr                ;
  1487.  
  1488.     sub.w    #ZAccel,Plyr_ZSpd        ; Plyr_ZSpd -= ZAccel
  1489.     cmp.w    #0,Plyr_ZSpd            ; IF Plyr_ZSpd < 0
  1490.     bge.b    .outt0                ;   Plyr_ZSpd = 0
  1491.     move.w    #0,Plyr_ZSpd            ; ENDIF
  1492.     move.w    #0,Plyr_XSpd            ;
  1493.     move.w    #0,Plyr_YSpd            ;
  1494.     move.w    #FALSE,Plyr_EngineOn        ; Stop engine
  1495.  
  1496. .outt0    tst.l    Toggle                ; IF Toggle-bit set
  1497.     beq.b    .outt1                ;
  1498.     CPUTSTR    txt_out,#36+60*160        ; THEN Write "OUT"
  1499.     CPUTSTR    txt_of,#68+60*160        ;      Write "OF"
  1500.     CPUTSTR    txt_time,#92+60*160        ;      Write "TIME"
  1501.  
  1502. .outt1    cmp.l    #250,FlgTimer            ; IF FlgTimer > 5 secs
  1503.     ble.w    .Keys                ;
  1504.     move.l    #Flg_Quit,Game_Flags        ;   Game_Flags=Flg_Quit
  1505.     bra.w    .Keys                ; ENDIF
  1506.  
  1507.     ; RaceOver ------------------------------------------------------------
  1508.  
  1509. .racovr    cmp.l    #Flg_RaceOver,Game_Flags    ; Race Over
  1510.     bne.b    .pause                ;
  1511.  
  1512.     tst.l    Toggle                ; IF Toggle-bit set
  1513.     beq.b    .racov1                ;
  1514.     CPUTSTR    txt_race,#44+60*160        ; THEN Write "RACE"
  1515.     CPUTSTR    txt_over,#84+60*160        ;      Write "OVER"
  1516.  
  1517. .racov1    cmp.l    #250,FlgTimer            ; IF FlgTimer > 5 secs
  1518.     ble.w    .Keys                ;
  1519.     move.l    #Flg_Quit,Game_Flags        ;   Game_Flags=Flg_Quit
  1520.     bra.w    .Keys                ; ENDIF
  1521.  
  1522.     ; Pause ---------------------------------------------------------------
  1523.  
  1524. .pause    cmp.l    #Flg_Pause,Game_Flags        ; Game paused
  1525.     bne.b    .EndFlg                ; 
  1526.  
  1527.     tst.l    Toggle                ; IF Toggle-bit set
  1528.     beq.b    .pause1                ;
  1529.     CPUTSTR    txt_pause,#60+60*160        ; THEN Write "PAUSE"
  1530.  
  1531. .pause1    bsr.w    GetKey                ; Read keyboard
  1532.     cmp.b    #KEY_NEW,KeyState        ; IF previous key repeated
  1533.     bne.w    .Done                ; THEN skip everything
  1534.     cmp.b    #KEY_P,KeyRaw            ; 
  1535.     bne.w    .Done                ; IF P was pressed
  1536.     move.l    #Flg_Normal,Game_Flags        ;   Resume game
  1537.     bra.w    .Done                ; ENDIF
  1538.  
  1539. .EndFlg    bra.w    .Keys                ; Unknown flag. Never get here!
  1540.     
  1541.     ; Handle joystick input -----------------------------------------------
  1542.  
  1543. .Player    bsr.w    GetJoy1            ; Read joystick
  1544.  
  1545.     move.l    RealTime,d0        ; 
  1546.     move.l    #ZAccel,d1        ; ZAccel = RealTime * ZAccel
  1547.     mulu.w    d0,d1            ;
  1548.     move.l    #XAccel,d2        ; XAccel = RealTime * XAccel
  1549.     mulu.w    d0,d2            ;
  1550.     move.l    #YAccel,d3        ; YAccel = RealTime * YAccel
  1551.     mulu.w    d0,d3            ;
  1552.  
  1553.     tst.b    Joy1Fire        ; Fire ?
  1554.     beq.b    .nofire            ;
  1555.  
  1556.     move.w    #TRUE,Plyr_EngineOn    ;   Activate engine
  1557.  
  1558.     add.w    d1,Plyr_ZSpd        ;   Plyr_ZSpd += ZAccel
  1559.     cmp.w    #MaxSpd,Plyr_ZSpd    ;   IF Plyr_ZSpd > MaxSpd
  1560.     ble.b    .tstup            ;
  1561.     move.w    #MaxSpd,Plyr_ZSpd    ;     Plyr_ZSpd = MaxSpd
  1562.     bra.b    .tstup            ;   ENDIF
  1563. .nofire
  1564.     move.w    #FALSE,Plyr_EngineOn    ;   Stop engine
  1565.     
  1566.     sub.w    d1,Plyr_ZSpd        ;   Plyr_ZSpd -= ZAccel
  1567.     cmp.w    #MinSpd,Plyr_ZSpd    ;   IF Plyr_ZSpd < MinSpd
  1568.     bge.b    .tstup            ;     Plyr_ZSpd = MinSpd
  1569.     move.w    #MinSpd,Plyr_ZSpd    ;   ENDIF
  1570. .tstup                    ;   
  1571.     tst.b    Joy1Up            ; Up ?
  1572.     beq.b    .noup            ;
  1573.     sub.w    d3,Plyr_YSpd        ;   Plyr_YSpd -= YAccel
  1574.     bra.b    .tstdn            ;
  1575. .noup    tst.w    Plyr_YSpd        ;   IF Plyr_YSpd < 0
  1576.     bpl.b    .tstdn            ;
  1577.     add.w    d3,Plyr_YSpd        ;     Plyr_YSpd += YAccel
  1578.     bmi.b    .tstdn            ;     IF Plyr_YSpd > 0 THEN Plyr_YSpd=0
  1579.     move.w    #0,Plyr_YSpd            ;   ENDIF
  1580. .tstdn                    ;   
  1581.     tst.b    Joy1Down        ; Down ?
  1582.     beq.b    .nodn            ;
  1583.     add.w    d3,Plyr_YSpd        ;   Plyr_YSpd += YAccel
  1584.     bra.b    .tstlt            ;
  1585. .nodn    tst.w    Plyr_YSpd        ;   IF Plyr_YSpd > 0
  1586.     bmi.b    .tstlt            ;
  1587.     sub.w    d3,Plyr_YSpd        ;     Plyr_YSpd -= YAccel
  1588.     bpl.b    .tstlt            ;     IF Plyr_YSpd < 0 THEN Plyr_YSpd=0
  1589.     move.w    #0,Plyr_YSpd            ;   ENDIF    
  1590. .tstlt                    ;   
  1591.     tst.b    Joy1Left        ; Left ?
  1592.     beq.b    .nolt            ;
  1593.     sub.w    d2,Plyr_XSpd        ;   Plyr_XSpd -= XAccel
  1594.     bra.b    .tstrt            ;
  1595. .nolt    tst.w    Plyr_XSpd        ;   IF Plyr_XSpd < 0
  1596.     bpl.b    .tstrt            ;
  1597.     add.w    d2,Plyr_XSpd        ;     Plyr_XSpd += XAccel
  1598.     bmi.b    .tstrt            ;     IF Plyr_XSpd > 0 THEN Plyr_XSpd=0
  1599.     move.w    #0,Plyr_XSpd            ;   ENDIF    
  1600. .tstrt                    ;   
  1601.     tst.b    Joy1Right        ; Right ?
  1602.     beq.b    .nort            ;
  1603.     add.w    d2,Plyr_XSpd        ;   Plyr_XSpd += XAccel
  1604.     bra.b    .Keys            ;
  1605. .nort    tst.w    Plyr_XSpd        ;   IF Plyr_XSpd > 0
  1606.     bmi.b    .Keys            ;
  1607.     sub.w    d2,Plyr_XSpd        ;     Plyr_XSpd -= XAccel
  1608.     bpl.b    .Keys            ;     IF Plyr_XSpd < 0 THEN Plyr_XSpd=0
  1609.     move.w    #0,Plyr_XSpd            ;   ENDIF
  1610.  
  1611.     ; Handle keyboard input -----------------------------------------------
  1612.  
  1613. .Keys    bsr.w    GetKey            ; Read keyboard input
  1614.     cmp.b    #KEY_NEW,KeyState    ; IF previous key repeated
  1615.     bne.b    .move               ; THEN skip this part
  1616.     
  1617.     move.b    KeyRaw,d0        ;
  1618.     cmp.b    #KEY_ESC,d0        ; IF ESC pressed ?
  1619.     bne.b    .P            ;  
  1620.     move.l    #Flg_Quit,Game_Flags    ;   Game_Flags=Flg_Quit
  1621.     bra.w    .Done            ; ENDIF
  1622.  
  1623. .P    cmp.b    #KEY_P,d0        ; IF P pressed ?
  1624.     bne.b    .move            ;   
  1625.     cmp.l    #Flg_Normal,Game_Flags    ;   IF Game_Flags=Flg_Normal
  1626.     bne.b    .move            ;   
  1627.     move.l    #Flg_Pause,Game_Flags    ;   THEN Game_Flags=Flg_Pause
  1628.     bra.w    .Done            ; ENDIF
  1629.  
  1630.     ; Move player ---------------------------------------------------------
  1631.  
  1632. .move    moveq    #0,d0            ; 
  1633.     move.w    Plyr_ZSpd,d0        ; Plyr_Scroll += Plyr_ZSpd
  1634.     add.w    d0,Plyr_Scroll        ;
  1635.     lsr.w    #8,d0            ; Plyr_Z += (Plyr_ZSpd/256)
  1636.     add.l    d0,Plyr_Z        ;
  1637.  
  1638.     move.w    Plyr_XSpd,d0        ; Plyr_X += Plyr_XSpd
  1639.     add.w    d0,Plyr_X        ;
  1640.     move.w    Plyr_YSpd,d0        ; Plyr_Y += Plyr_YSpd
  1641.     add.w    d0,Plyr_Y        ;
  1642.  
  1643.     ; Check for boundaries ------------------------------------------------
  1644.  
  1645.     move.w    Plyr_X,d0        ;
  1646.     cmp.w    #Plyr_XMin,d0        ; IF Plyr_X < Plyr_XMin
  1647.     bge.b    .chkrt            ;
  1648.     move.w    #Plyr_XMin,Plyr_X    ;   Plyr_X = Plyr_XMin
  1649.     move.w    #0,Plyr_XSpd        ;   Plyr_XSpd = 0
  1650.     bra.b    .chkup            ;
  1651. .chkrt    cmp.w    #Plyr_XMax,d0        ; ELSEIF Plyr_X > Plyr_XMax
  1652.     ble.b    .chkup            ;   Plyr_X = Plyr_XMax
  1653.     move.w    #Plyr_XMax,Plyr_X    ;   Plyr_XSpd = 0
  1654.     move.w    #0,Plyr_XSpd        ; ENDIF
  1655. .chkup    move.w    Plyr_Y,d0        ; 
  1656.     cmp.w    #Plyr_YMin,d0        ; IF Plyr_Y < Plyr_YMin
  1657.     bge.b    .chkdn            ;
  1658.     move.w    #Plyr_YMin,Plyr_Y    ;   Plyr_Y = Plyr_YMin
  1659.     move.w    #0,Plyr_YSpd        ;   Plyr_YSpd = 0
  1660.     bra.b    .Time            ;
  1661. .chkdn    cmp.w    #Plyr_YMax,d0        ; ELSEIF Plyr_Y > Plyr_YMax
  1662.     ble.b    .Time            ;   Plyr_Y = Plyr_YMax
  1663.     move.w    #Plyr_YMax,Plyr_Y    ;   Plyr_YSpd = 0
  1664.     move.w    #0,Plyr_YSpd        ; ENDIF
  1665.  
  1666.     ; Check Time ----------------------------------------------------------
  1667.  
  1668. .Time    cmp.l    #Flg_Normal,Game_Flags        ; IF Flg_Normal not set
  1669.     bne.b    .Done                ; THEN skip this part
  1670.     cmp.l    #0,Plyr_Time            ;
  1671.     bgt.b    .Done                ; IF Plyr_Time <= 0
  1672.     move.l    #0,Plyr_Time            ; THEN Plyr_Time=0
  1673.     move.l    #Flg_OutOfTime,Game_Flags    ;      Game_Flags=Flg_OutOfTime
  1674.  
  1675.     ; Finished ------------------------------------------------------------
  1676. .Done
  1677.  
  1678.     IFNE     DEBUG                ;
  1679.        btst     #2,$dff016            ; Check right mousebutton 
  1680.     bne.b    .z                ;
  1681.     move.l    #Flg_Quit,Game_Flags        ;
  1682. .z    ENDC                    ;
  1683.  
  1684.     movem.l    (sp)+,d0-d7/a0-a6        ; Restore regs
  1685.     rts
  1686.  
  1687.  
  1688. ; *****************************************************************************
  1689. ; DrawPlayer
  1690. ; -----------------------------------------------------------------------------
  1691. ; Inputs     : -
  1692. ; Output     : -
  1693. ; Description: Draws player. Draws shadow. Changes engine colour.
  1694. ; Notes      : -
  1695. ; Scratch    : All
  1696. ; Author     : -
  1697. ; History    : -
  1698. ; *****************************************************************************
  1699.  
  1700.     ALIGNLONG
  1701.     
  1702. DrawPlayer
  1703.     cmp.l    #Flg_Collision,Game_Flags    ; IF Flg_Collision
  1704.     beq.w    .Done                ; THEN don't draw player 
  1705.     cmp.l    #Flg_RaceOver,Game_Flags    ; IF Flg_RaceOver
  1706.     beq.w    .Done                ; THEN don't draw player
  1707.  
  1708.     ; Calculate destination pointers --------------------------------------
  1709.     
  1710.     movem.l    d0-d7/a0-a6,-(sp)    ;
  1711.     move.l    RendCh,a1        ; a1 = Pointer for ship
  1712.     moveq    #0,d0            ;
  1713.     moveq    #0,d1            ;
  1714.     move.w    Plyr_Y,d0        ;
  1715.     sub.w    #12,d0            ; Adjust Y-position
  1716.     move.w    d0,d1            ; }
  1717.     lsl.w    #7,d0            ; }_ Y * 160
  1718.     lsl.w    #5,d1            ; }
  1719.     add.w    d1,d0            ; }
  1720.     add.l    d0,a1            ;
  1721.     move.w    Plyr_X,d1        ;
  1722.     sub.w    #21,d1            ; Adjust X-position
  1723.     add.l    d1,a1            ; 
  1724.  
  1725.     move.l    RendCh,a3        ; a3 = Pointer for shadow
  1726.     add.l    d1,a3            ; 
  1727.     add.l    #100*160,a3        ; Y-position
  1728.  
  1729.     ; In what column is player ? ------------------------------------------
  1730.  
  1731.     moveq    #0,d1            ;    
  1732.     move.w    Plyr_X,d1        ; 
  1733.     sub.w    #32-12,d1        ; Adjust X-postion
  1734.     divu.w    #24,d1            ; Col.nr = X-position / Column_width
  1735.     move.w    d1,d0            ;
  1736.     move.w    d1,d4            ; ShadowFrame.nr = Col.nr
  1737.     lsl.w    #2,d0            ; Frame.nr = Col.nr * 5
  1738.     add.w    d1,d0            ; 
  1739.  
  1740.     ; In what row is player ? ---------------------------------------------
  1741.  
  1742.     moveq    #0,d2            ;
  1743.     move.w    Plyr_Y,d2        ;
  1744.     sub.w    #32-8,d2        ; Adjust Y-position
  1745.     lsr.w    #4,d2            ; Row.nr = Y-postion / Row_height
  1746.     add.w    d2,d0            ; Frame.nr += Row.nr
  1747.     move.w    d0,Plyr_Frame        ; Store frame number (for coll. checks)
  1748.  
  1749.     ; Draw shadow ---------------------------------------------------------
  1750.  
  1751.     lea    Shadow_Anim,a2        ;
  1752.     move.l    (a2,d4.w*4),a0        ; Get source pointer
  1753.     
  1754.     move.l    #25-1,d6        ; Height = 25 lines
  1755. .sloop1    move.w    #48-1,d7        ; Width  = 48 columns (actually 42!)
  1756. .sloop2    move.b    (a0)+,d1        ; Read byte
  1757.     beq.b    .sskip            ; IF transparent THEN skip write
  1758.     move.b    d1,(a3)            ; Write byte        
  1759. .sskip    addq.l    #1,a3            ; Go to next pixel
  1760.     dbf    d7,.sloop2        ;
  1761.     add.l    #160-48,a3        ; Go to next row
  1762.     dbf    d6,.sloop1        ;
  1763.  
  1764.     ; Draw ship -----------------------------------------------------------
  1765.  
  1766.     lea    Ship_Anim,a2        ;
  1767.     move.l    (a2,d0.w*4),a0        ; Get source pointer
  1768.  
  1769.     move.l    #25-1,d6        ; Height = 25 lines
  1770. .loop1    move.w    #48-1,d7        ; Width  = 48 columns (actually 42!)
  1771. .loop2    move.b    (a0)+,d0        ; Read byte
  1772.     beq.b    .skip            ; IF transparent THEN skip write
  1773.     move.b    d0,(a1)            ; Write byte        
  1774. .skip    addq.l    #1,a1            ; Go to next pixel
  1775.     dbf    d7,.loop2        ;
  1776.     add.l    #160-48,a1        ; Go to next row
  1777.     dbf    d6,.loop1        ;
  1778.  
  1779.     ; Change engine colour in copperlist ----------------------------------
  1780.  
  1781.     move.w    Plyr_EngineCnt,d0    ; d0 = Offset in colour table
  1782.     cmp.w    #TRUE,Plyr_EngineOn    ; IF Plyr_EngineOn = TRUE
  1783.     bne.b    .false            ;
  1784.     addq.w    #1,d0            ;   Plyr_EngineCnt += 1
  1785.     cmp.w    #7,d0            ;   IF Plyr_EngineCnt > 7
  1786.     ble.b    .store            ;   THEN Plyr_EngineCnt = 7
  1787.     moveq    #7,d0            ;
  1788.     bra.b    .store            ; ELSE
  1789. .false    subq.w    #1,d0            ;   Plyr_EngineCnt -= 1
  1790.     bpl.b    .store            ;   IF Plyr_EngineCnt < 0
  1791.     moveq    #0,d0            ;   THEN Plyr_EngineCnt = 0
  1792. .store    move.w    d0,Plyr_EngineCnt    ; ENDIF    
  1793.  
  1794.      lea    EnginePal,a1        ; a1 = Pointer to colour table
  1795.     move.l    (a1,d0.w*4),d1        ; d1 = Colour (24-Bit HLi)
  1796.  
  1797.     move.l    RendCop,a0        ; a0 = Pointer to copperlist
  1798.     add.l    #CopCol-Cop+394,a0    ;
  1799.     move.w    d1,132(a0)        ; Write low 12 bits
  1800.     swap    d1            ;
  1801.     move.w    d1,(a0)            ; Write high 12 bits
  1802.  
  1803.     movem.l    (sp)+,d0-d7/a0-a6    ;
  1804.  
  1805.     ; Finished ------------------------------------------------------------
  1806. .Done
  1807.     rts
  1808.  
  1809.         
  1810. ; *****************************************************************************
  1811. ; DoWalls
  1812. ; -----------------------------------------------------------------------------
  1813. ; Inputs     : -
  1814. ; Output     : -
  1815. ; Description: Draws all visible walls and player.
  1816. ; Notes      : -
  1817. ; Scratch    : All
  1818. ; History    : -
  1819. ; *****************************************************************************
  1820.  
  1821.     ALIGNLONG
  1822.     
  1823. DoWalls
  1824.     ; Check if FirstWall is still visible ---------------------------------
  1825.  
  1826.     move.l    Game_LevelPtr,a1    ; a1 = Pointer to Level array
  1827.     move.w    Level_NumWall(a1),d1    ;
  1828.     subq.w    #1,d1            ; d1 = Level_NumWall-1
  1829.  
  1830.     move.l    Game_WallZ,a4        ; a4 = Pointer to Wall_Z array
  1831.     move.l    Plyr_Z,d2        ; d2 = Plyr_Z
  1832.     move.w    Game_FirstWall,d0    ; d0 = Game_FirstWall
  1833.     move.l    (a4,d0.w*4),d3        ; d3 = Wall_Z[Game_FirstWall]
  1834.     cmp.l    d2,d3            ;
  1835.     bgt.b    .levcpl            ; IF d3 <= d2
  1836.     addq.w    #1,d0            ; THEN Game_FirstWall += 1
  1837.     move.w    d0,Game_FirstWall    ;
  1838.  
  1839.     ; Check if level is completed -----------------------------------------
  1840.     
  1841. .levcpl    cmp.l    #Flg_Normal,Game_Flags    ; IF Game_Flags <> Flg_Normal
  1842.     bne.b    .chk1            ; THEN skip this bit
  1843.     move.l    (a4,d0.w*4),d3        ; d3 = Wall_Z[Game_FirstWall]
  1844.     sub.l    d2,d3            ; d3 = Wall_Z[FW]-Plyr_Z
  1845.     cmp.l    #RealZ,d3        ;
  1846.     bge.b    .chk1            ; IF d3 < RealZ
  1847.     cmp.w    d1,d0            ;
  1848.     bne.b    .chk1            ; AND Game_FirstWall = Level_NumWall-1
  1849.     move.l    #Flg_LevelDone,Game_Flags ; THEN level complete !!!
  1850.     
  1851.     ; Check if a new wall becomes visible ---------------------------------
  1852.  
  1853. .chk1    move.w    Game_LastWall,d0    ; d0 = Game_LastWall
  1854.     cmp.w    d1,d0            ;
  1855.     blt.b    .chk2            ; IF Game_LastWall >= Level_NumWall-1
  1856.     move.w    d1,Game_LastWall    ; THEN Game_LastWall = Level_NumWall-1
  1857.     bra.b    .Draw
  1858. .chk2    addq.w    #1,d0            ; d0 = Game_LastWall+1
  1859.     move.l    (a4,d0.w*4),d1        ; d1 = Wall_Z[Game_LastWall+1]
  1860.     add.l    #ViewD,d2        ; d2 = Plyr_Z + ViewD
  1861.     cmp.l    d2,d1            ;  
  1862.     bge.b    .Draw            ; IF d1 < d2
  1863.     move.w    d0,Game_LastWall    ; THEN Game_LastWall += 1
  1864.     
  1865.     ; Draw the visible walls back to front --------------------------------
  1866. .Draw
  1867.     move.l    #WallLut_X,a1        ;
  1868.     move.l    #WallLut_Y,a2        ;
  1869.     move.l    #WallLut_S,a3        ;
  1870.     move.w    Game_LastWall,d7    ;
  1871.     move.w    d7,d0            ; t=LastWall
  1872.     sub.w    Game_FirstWall,d7    ; d7=LastWall-FirstWall (loop counter)
  1873.     sub.w    #1,d7            ; d7=LastWall-FirstWall-1 
  1874.     bmi.b    .First            ; 
  1875. .drwlop                    ; FOR (t=LastWall; t>=FirstWall-1; t--)
  1876.     move.l    (a4,d0.w*4),d1        ;   d1 = Wall_Z[t]
  1877.     sub.l    Plyr_Z,d1        ;   RelZ = Wall_Z[t] - Plyr_Z
  1878.         
  1879.     movem.l    d0/d1/d7/a0-a3,-(sp)    ;
  1880.     move.l    (a1,d1.w*4),d2        ;   BufferX
  1881.     move.l    (a2,d1.w*4),d3        ;   BufferY
  1882.     move.l  (a3,d1.w*4),d4        ;   Size
  1883.     
  1884.     move.l    Game_WallType,a1    ;   a1 = Pointer to Wall_Type array
  1885.     move.l    #Type_Bitmap,a0        ;
  1886.     move.w    (a1,d0.w*2),d6        ;   d6 = Wall_Type[t]
  1887.     move.l    (a0,d6.w*4),a0         ;   SourcePtr = Type_Bitmap[Wall_Type[t]]
  1888.     move.l    RendCh,a1        ;   BufferPtr
  1889.     bsr.w    ScaleWall        ;
  1890.     movem.l    (sp)+,d0/d1/d7/a0-a3    ;
  1891.  
  1892.     subq.w    #1,d0            ;       
  1893.     dbf    d7,.drwlop        ; NEXT t
  1894.  
  1895.     ; Draw FirstWall and player -------------------------------------------
  1896. .First
  1897.     move.l    (a4,d0.w*4),d1        ; d1 = Wall_Z[t]
  1898.     sub.l    Plyr_Z,d1        ; RelZ = Wall_Z[t] - Plyr_Z
  1899.  
  1900.     cmp.l    #ViewD,d1        ; IF d1 < ViewD
  1901.     bcs.b    .visible        ; THEN FirstWall is visible
  1902.     bsr.w    DrawPlayer        ; ELSE DrawPlayer 
  1903.     bra.w    .Done            ;      and leave !!!
  1904. .visible
  1905.     move.l    (a1,d1.w*4),d2        ; BufferX
  1906.     move.l    (a2,d1.w*4),d3        ; BufferY
  1907.     move.l  (a3,d1.w*4),d4        ; Size
  1908.     move.l    Game_WallType,a1    ; a1 = Pointer to Wall_Type array
  1909.     move.l    #Type_Bitmap,a0        ;
  1910.     move.w    (a1,d0.w*2),d6        ; d6 = Wall_Type[FirstWall]
  1911.     move.l    (a0,d6.w*4),a0         ; SourcePtr = Type_Bitmap[Wall_Type[FW]]
  1912.     move.l    RendCh,a1        ; BufferPtr
  1913.  
  1914.     move.l    d1,a4            ; save RelZ
  1915.     move.l    d6,a6            ; save Wall_Type[FirstWall]
  1916.     cmp.l    #RealZ,d1        ; IF d1 < RealZ
  1917.     bge.b    .else            ;
  1918.     bsr.w    DrawPlayer        ;   DrawPlayer()
  1919.     bsr.w    ScaleWall        ;   ScaleWall()
  1920.     bra.b    .TstColl        ; ELSE
  1921. .else    bsr.w    ScaleWall        ;   ScaleWall()
  1922.     bsr.w    DrawPlayer        ;   DrawPlayer()
  1923.  
  1924.     ; Test for collision --------------------------------------------------
  1925. .TstColl
  1926.     cmp.l    #Flg_Normal,Game_Flags    ; IF Game_Flags <> Flg_Normal
  1927.     bne.b    .Done            ; THEN skip collision check
  1928.     
  1929.     move.l    a4,d1            ; restore RelZ
  1930.     move.l    a6,d0            ; restore Wall_Type[FirstWall]
  1931.     cmp.l    #RealZ,d1        ; IF RelZ <= RealZ
  1932.     bgt.b    .Done            ;
  1933.     move.w    Plyr_ZSpd,d2        ;
  1934.     lsr.w    #8,d2            ;
  1935.     move.w    #RealZ,d3        ;
  1936.     sub.w    d2,d3            ;
  1937.     cmp.w    d3,d1            ; AND RelZ >= (RealZ-Plyr_ZSpd/256)
  1938.     blt.b    .Done            ;
  1939.     bsr.b    InHole            ; AND InHole(Wall_Type[FirstWall])==0
  1940.     bne.b    .Done            ;
  1941.     move.l    #Flg_Collision,Game_Flags ; THEN Collision !
  1942.     sub.w    #1,Plyr_Ships        ;   Plyr_Ships -= 1
  1943.  
  1944.     ; Finished ------------------------------------------------------------
  1945. .Done
  1946.     rts
  1947.  
  1948.  
  1949. ; *****************************************************************************
  1950. ; InHole
  1951. ; -----------------------------------------------------------------------------
  1952. ; Inputs     : d0.w = Type of wall
  1953. ; Output     : d0.l = 0 : Outside hole
  1954. ;              d0.l = 1 : Inside hole
  1955. ; Description: Determines if ship is _completely_ inside the hole a wall.
  1956. ; Notes      : -
  1957. ; Scratch    : d0
  1958. ; History    : -
  1959. ; *****************************************************************************
  1960.  
  1961.     ALIGNLONG
  1962.     
  1963. InHole
  1964.     movem.l    d1-d4/a0-a1,-(sp)        ; Save registers
  1965.     
  1966.     lea    Type_Hole,a0            ; Hole data
  1967.     lea    Coll_Bounds,a1            ; Collision bounds data
  1968.     move.w    Plyr_Frame,d3            ; Current player frame number
  1969.  
  1970.     move.w    Type_HoleX1(a0,d0.w*8),d2    ; IF (Plyr_X-Coll_BoundsX1)
  1971.     move.w    Plyr_X,d1            ;    < Type_HoleX1[Type] 
  1972.     move.w    Coll_BoundsX1(a1,d3.w*8),d4    ;    
  1973.     add.w    d4,d1                ;
  1974.     cmp.w    d2,d1                ; 
  1975.     blt.b    .Ret0                ; THEN return 0
  1976.  
  1977.     move.w    Type_HoleX2(a0,d0.w*8),d2    ; IF (Plyr_X+Coll_BoundsX2)
  1978.     move.w    Plyr_X,d1            ;    > Type_HoleX2[Type]
  1979.     move.w    Coll_BoundsX2(a1,d3.w*8),d4    ;
  1980.     add.w    d4,d1                ;
  1981.     cmp.w    d2,d1                ;
  1982.     bgt.b    .Ret0                ; THEN return 0
  1983.  
  1984.     move.w    Type_HoleY1(a0,d0.w*8),d2    ; IF (Plyr_Y-Coll_BoundsY1)
  1985.     move.w    Plyr_Y,d1            ;    < Type_HoleY1[Type]
  1986.     move.w    Coll_BoundsY1(a1,d3.w*8),d4    ;
  1987.     add.w    d4,d1                ;   
  1988.     cmp.w    d2,d1                ;
  1989.     blt.b    .Ret0                ; THEN return 0
  1990.  
  1991.     move.w    Type_HoleY2(a0,d0.w*8),d2    ; IF (Plyr_Y+Coll_BoundsY2)
  1992.     move.w    Plyr_Y,d1            ;    > Type_HoleY2[Type]
  1993.     move.w    Coll_BoundsY2(a1,d3.w*8),d4    ;
  1994.     add.w    d4,d1                ;
  1995.     cmp.w    d2,d1                ;    
  1996.     bgt.b    .Ret0                ; THEN return 0
  1997.  
  1998. .Ret1    moveq    #1,d0                ; Return 1
  1999.     movem.l    (sp)+,d1-d4/a0-a1        ; Restore registers
  2000.     rts
  2001. .Ret0    moveq    #0,d0                ; Return 0
  2002.     movem.l    (sp)+,d1-d4/a0-a1        ; Restore registers
  2003.     rts
  2004.  
  2005.  
  2006. ; *****************************************************************************
  2007. ; DrawTunnel
  2008. ; -----------------------------------------------------------------------------
  2009. ; Inputs     : -
  2010. ; Outputs    : -
  2011. ; Description: Draws the tunnel into the chunky buffer.
  2012. ; Notes      : -
  2013. ; Scratch    : d0,d1,d7,a0,a1,a2
  2014. ; Author     : Matthijs Hollemans
  2015. ; History    : 24 Dec 1996
  2016. ;              04 Jan 1997, Major speedup: writes longs instead of bytes.
  2017. ; *****************************************************************************
  2018.  
  2019.     ALIGNLONG
  2020.     
  2021. DrawTunnel
  2022.     moveq    #0,d0
  2023.     move.w    #160*128/4-1,d7        ; 20480 pixels
  2024.     move.l    RendCh,a0
  2025.     move.l    #txt,a1            ; Pointer to texture
  2026.     move.l    #TxtLut,a2        ; Pointer to texture LookUpTable
  2027.     move.w    Plyr_Scroll,d1
  2028. .loop    move.w    d1,d0            ; d0  = Scroll
  2029.     add.w    (a2)+,d0        ; d0 += Texture offset
  2030.     move.b    (a1,d0.l),d2        ; xxxxxxAA
  2031.     lsl.w    #8,d2            ; xxxxAAxx
  2032.     move.w    d1,d0            ; d0  = Scroll
  2033.     add.w    (a2)+,d0        ; d0 += Texture offset
  2034.     move.b    (a1,d0.l),d2        ; xxxxAABB
  2035.     swap    d2            ; AABBxxxx
  2036.     move.w    d1,d0            ; d0  = Scroll
  2037.     add.w    (a2)+,d0        ; d0 += Texture offset
  2038.     move.b    (a1,d0.l),d2        ; AABBxxCC
  2039.     lsl.w    #8,d2            ; AABBCCxx
  2040.     move.w    d1,d0            ; d0  = Scroll
  2041.     add.w    (a2)+,d0        ; d0 += Texture offset
  2042.     move.b    (a1,d0.l),d2        ; AABBCCDD
  2043.     move.l    d2,(a0)+        ; Store 4 pixels in chunky buffer
  2044.     dbf    d7,.loop
  2045.     rts
  2046.  
  2047.  
  2048. ; *****************************************************************************
  2049. ; ScaleWall
  2050. ; -----------------------------------------------------------------------------
  2051. ; Inputs     : a0   = SourcePtr
  2052. ;             a1   = BufferPtr
  2053. ;              d2.l = BufferX
  2054. ;              d3.l = BufferY
  2055. ;              d4.l = Destination Size (= width = height)
  2056. ;              d6.w = Walltype
  2057. ; Output     : -
  2058. ; Description: Scales a 128x128 chunky image.
  2059. ; Notes      : o Performs clipping.
  2060. ;              o Does not perform mirroring.
  2061. ;              o Destination coordinates are allowed to be negative.
  2062. ;              o Colour 0 is transparent.
  2063. ; Scratch    : d0-d7/a0-a3/a5
  2064. ; Author     : Matthijs Hollemans
  2065. ; History    : 27 Dec 1996
  2066. ;              04 Jan 1997, On some walls (WT_Left/Right/Up/Down) a lot of
  2067. ;                           transparent pixels were scaled, wasting time.
  2068. ; *****************************************************************************
  2069.  
  2070.     ALIGNLONG
  2071.     
  2072. ScaleWall
  2073.     ; Determine step size -------------------------------------------------
  2074.  
  2075.     move.l    d4,d5            ; ClipW = ClipH = Destination Size
  2076.     move.l    #$8000,d0        ; XStep = SourceW << 8
  2077.     divu    d4,d0            ; XStep = (SourceW << 8) / DestW
  2078.     andi.l    #$ffff,d0        ; Get rid of remainder
  2079.     move.l    d0,d1            ; YStep = XStep
  2080.  
  2081.     ; Special type ? ------------------------------------------------------
  2082.  
  2083.     cmp.w    #WT_Left,d6        ; IF Walltype=WT_Left
  2084.     bne.b    .nolt            ;
  2085.     lsr.l    #1,d4            ;   ClipW /= 2
  2086.     bra.b    .Clip            ; ENDIF
  2087. .nolt    cmp.w    #WT_Right,d6        ; IF Walltype=WT_Right
  2088.     bne.b    .nort            ;
  2089.     lsr.l    #1,d4            ;   ClipW / 2
  2090.     move.l    #CenterX,d2        ;   BufferX = CenterX
  2091.     bra.b    .Clip            ; ENDIF
  2092. .nort    cmp.w    #WT_Up,d6        ; IF Walltype=WT_Up
  2093.     bne.b    .noup            ;
  2094.     lsr.l    #1,d5            ;   ClipH / 2 
  2095.     bra.b    .Clip            ; ENDIF
  2096. .noup    cmp.w    #WT_Down,d6        ; IF Walltype=WT_Down
  2097.     bne.b    .Clip            ;   ClipH / 2
  2098.     lsr.l    #1,d5            ;   BufferY = CenterY
  2099.     move.l    #CenterY,d3        ; ENDIF
  2100.     
  2101.     ; Clipping ------------------------------------------------------------
  2102.  
  2103. .Clip    moveq    #0,d6            ; SY = 0
  2104.     cmp.l    #ClipT,d3        ; IF BufferY < ClipT
  2105.     bge.b    .Bottom            ;
  2106.     move.l    #ClipT,d6        ;   d6 = ClipT
  2107.     sub.l    d3,d6            ;   d6 = ClipT - BufferY
  2108.     sub.l    d6,d5            ;   d5 -= ClipT - BufferY
  2109.     mulu    d1,d6            ;   d6 = (ClipT - BufferY) * YStep
  2110.     move.l    #ClipT,d3        ;   d3 = ClipT
  2111. .Bottom                    ; ENDIF
  2112.     move.l    d3,d7            ; d7 = BufferY
  2113.     add.l    d5,d7            ; d7 = BufferY + ClipH
  2114.     cmp.l    #ClipB,d7        ; IF (BufferY + ClipH) > ClipB
  2115.     ble.b    .Left            ;
  2116.     move.l    #ClipB,d5        ;   d5 = ClipB
  2117.     sub.l    d3,d5            ;   d5 = ClipB - BufferY
  2118.     addq.l    #1,d5            ;   d5 = ClipB - BufferY + 1
  2119. .Left                    ; ENDIF
  2120.     mulu    #BufferW,d3        ; d3 = BufferY * BufferW
  2121.     add.l    d3,a1            ; a1 += BufferY * BufferW
  2122.     moveq    #0,d3            ; StartSX = 0
  2123.  
  2124.     cmp.l    #ClipL,d2        ; IF BufferX < ClipL
  2125.     bge.b    .Right            ;
  2126.     move.l    #ClipL,d3        ;   d3 = ClipL
  2127.     sub.l    d2,d3            ;   d3 = ClipL - BufferX
  2128.     sub.l    d3,d4            ;   d4 -= (ClipL - BufferX)
  2129.     mulu    d0,d3            ;   d3 = (ClipL - BufferX) * XStep
  2130.     move.l    #ClipL,d2        ;   d2 = ClipL
  2131. .Right                    ; ENDIF
  2132.     move.l    d2,d7            ; d7 = BufferX
  2133.     add.l    d4,d7            ; d7 = BufferX + ClipW
  2134.     cmp.l    #ClipR,d7        ; IF (BufferX + ClipW) > ClipR
  2135.     ble.b    .ClpEnd            ;
  2136.     move.l    #ClipR,d4        ;   d4 = ClipR
  2137.     sub.l    d2,d4            ;   d4 = ClipR - BufferX
  2138.     addq.l    #1,d4            ;   d4 = ClipR - BufferX + 1
  2139. .ClpEnd                    ; ENDIF
  2140.     add.l    d2,a1            ; a1 += BufferX
  2141.     move.l    #BufferW,a3        ; a3 = BufferW
  2142.     sub.l    d4,a3            ; a3 = BufferW - ClipW
  2143.     subq.l    #1,d4            ; ClipW-1
  2144.     bmi.b    .Done            ; IF ClipW < 0 THEN Done
  2145.     subq.l    #1,d5            ; ClipH-1
  2146.     bmi.b    .Done            ; IF ClipH < 0 THEN Done
  2147.     move.l    d3,a5            ; a5 = StartSX
  2148.         
  2149.     ; Scaling -------------------------------------------------------------
  2150.  
  2151.     ; a0 = SourcePtr, a1 = BufferPtr, a2 = SourceLoop, a3 = BufferStep
  2152.     ; a5 = StartSX
  2153.     ; d0 = XStep, d1 = YStep, d2 = SX (only in ColLoop)
  2154.     ; d3 = scratch, d4 = ColLoop counter backup
  2155.     ; d5 = RowLoop counter, d6 = SY, d7 = ColLoop counter
  2156.  
  2157. .RowLoop                ; FOR (i=0; i < ClipH; i++)
  2158.     move.l    d6,d2            ;   d2 = SY
  2159.     movea.l    a0,a2            ;   a2 = SourcePtr
  2160.  
  2161.     lsr.l    #1,d2            ;   d2 = (SY >> 8)
  2162.     andi.l    #$ffffff80,d2        ;   d2 = (SY >> 8) * SourceW
  2163.     add.l    d2,a2            ;   a2 = SourcePtr + (SY >> 8)*SourceW
  2164.  
  2165.     move.l    a5,d2            ;   d2 = StartSX
  2166.     move.l    d4,d7            ;   FOR (j=0; j < ClipW; j++)
  2167. .ColLoop                ;    
  2168.     move.l    d2,d3            ;
  2169.     lsr.l    #8,d3            ;     d3 = SX >> 8
  2170.     add.l    d0,d2            ;     d2 += XStep
  2171.     move.b    (a2,d3.w),d3        ;     d3 = *(SourceLoop + (SX >> 8))
  2172.     beq.b    .NxtCol            ;     IF d3 == 0 THEN don't draw
  2173.     move.b    d3,(a1)            ;     *BufferPtr = d3
  2174. .NxtCol    addq.l    #1,a1            ;     BufferPtr += 1
  2175.     dbf    d7,.ColLoop        ;   ENDFOR
  2176.  
  2177.     adda.l    a3,a1            ;   a1 += BufferStep
  2178.     add.l    d1,d6            ;   d6 += YStep
  2179.     dbf    d5,.RowLoop        ; ENDFOR
  2180.  
  2181.     ; Finished ------------------------------------------------------------
  2182. .Done    
  2183.     rts
  2184.  
  2185.  
  2186. ; *****************************************************************************
  2187. ; MyVBLHandler
  2188. ; -----------------------------------------------------------------------------
  2189. ; Inputs     : -
  2190. ; Output     : -
  2191. ; Description: Custom VBL interrupt handler. Takes care of timers and stuff.
  2192. ; Notes      : Called from int3.
  2193. ; Scratch    : -
  2194. ; Author     : -
  2195. ; History    : -
  2196. ; *****************************************************************************
  2197.  
  2198. MyVBLHandler
  2199.     ; Toggle --------------------------------------------------------------
  2200.     
  2201.     move.l    ToggleCnt,d0            ; ToggleCnt += 1
  2202.     add.l    #1,d0                ;
  2203.     cmp.l    #20,d0                ; IF ToggleCnt > 20
  2204.     blt.b    .notogl                ;
  2205.     bchg    #0,Toggle            ;   Toggle
  2206.     moveq    #0,d0                ;   ToggleCnt=0
  2207. .notogl    move.l    d0,ToggleCnt            ; ENDIF
  2208.  
  2209.     ; RealTime ------------------------------------------------------------
  2210.  
  2211.     add.l    #1,RealTimeCnt            ; RealTimeCnt += 1
  2212.  
  2213.     ; Timers --------------------------------------------------------------
  2214.  
  2215.     cmp.l    #Flg_Normal,Game_Flags        ; IF Flg_Normal
  2216.     bne.b    .spcial                ;
  2217.     move.l    #0,FlgTimer            ; THEN FlgTimer = 0
  2218.     sub.l    #1,Plyr_Time            ;      Plyr_Time -= 1
  2219.     bra.b    .tstcol                ; 
  2220. .spcial    add.l    #1,FlgTimer            ; ELSE FlgTimer += 1
  2221.  
  2222. .tstcol    cmp.l    #Flg_Collision,Game_Flags    ; IF Flg_Collision
  2223.     bne.b    .Coll                ;
  2224.     sub.l    #1,Plyr_Time            ; THEN Plyr_Time -= 1
  2225.     
  2226.     ; Collision Fade ------------------------------------------------------
  2227. .Coll
  2228.     cmp.l    #Flg_Collision,Game_Flags    ; IF not collision
  2229.     beq.b    .coll1                ; 
  2230.     cmp.l    #Flg_RaceOver,Game_Flags    ; OR race over
  2231.     bne.b    .Done                ; THEN skip this part
  2232.  
  2233. .coll1    cmp.l    #1,FlgTimer            ; IF FlgTimer = 1
  2234.     blt.b    .Done                ;
  2235.     bgt.b    .coll0                ;
  2236.     move.l    RendCop,a0            ;
  2237.     add.l    #CopCol-Cop,a0            ;
  2238.     move.l    #WhitePal,a1            ;
  2239.     bsr.w    SetPal24            ;   Make screen totally white
  2240.     move.l    #WhitePal,a0            ;
  2241.     move.l    #TempPal,a1            ;
  2242.     bsr.w    CopyPal24            ;
  2243.     move.b    #5,d0                ;
  2244.     bsr.w    InitXFade            ;   Initialise crossfade
  2245.     bra.b    .Done                ;
  2246. .coll0    move.l    #TempPal,a0            ; ELSEIF FlgTimer > 1
  2247.     move.l    #GamePal,a1            ;
  2248.     bsr.w    XFade                ;
  2249.     move.l    RendCop,a0            ;   Crossfade white to 
  2250.     add.l    #CopCol-Cop,a0            ;   original game palette
  2251.     move.l    #TempPal,a1            ;
  2252.     bsr.w    SetPal24            ; ENDIF
  2253.  
  2254.     ; Finished ------------------------------------------------------------
  2255. .Done
  2256.     rts
  2257.  
  2258.  
  2259. ; *****************************************************************************
  2260. ; LoadScores
  2261. ; -----------------------------------------------------------------------------
  2262. ; Inputs     : -
  2263. ; Output     : -
  2264. ; Description: Stores default values in BestTimes and BestNames arrays.
  2265. ; Notes      : -
  2266. ; Scratch    : All
  2267. ; Author     : Matthijs Hollemans
  2268. ; History    : 23 Jan 1997
  2269. ; *****************************************************************************
  2270.  
  2271.     ALIGNLONG
  2272.     
  2273. LoadScores
  2274.     lea    BestTimes,a0        ;
  2275.     lea    BestNames,a1        ;
  2276.     move.w    #9-1,d7            ; 
  2277. .loop0    move.l    #29950,(a0)+        ; Write default time
  2278.     move.l    #"NOBO",(a1)+        ; }
  2279.     move.l    #"DY  ",(a1)+        ; }- Write default name
  2280.     move.l    #$20202000,(a1)+    ; }
  2281.     dbf    d7,.loop0        ;
  2282.     rts
  2283.  
  2284.  
  2285. ; =============================================================================
  2286. ;                             S U B R O U T I N E S
  2287. ;
  2288. ; =============================================================================
  2289.  
  2290.  
  2291. ; *****************************************************************************
  2292. ; PPutChr 
  2293. ; -----------------------------------------------------------------------------
  2294. ; Inputs     : a1   = Pointer to first bitplane
  2295. ;            d0.l = ASCII character
  2296. ; Output     : -
  2297. ; Description: Planar Put Character.
  2298. ; Notes      : -
  2299. ; Scratch    : d0,d1,d2,d7,a2,a3,a5
  2300. ; Author     : Matthijs Hollemans
  2301. ; History    : 06 Jan 1997
  2302. ; *****************************************************************************
  2303.  
  2304.     ALIGNLONG
  2305.     
  2306. PPutChr
  2307.     lea    IntroFont,a2        ; a2 = Pointer to gfx
  2308.     sub.l    #32,d0            ; Convert ASCII
  2309.     move.l    d0,d1            ; d0 = Offset for plane 7 gfx
  2310.     add.w    #1024,d1        ; d1 = Offset for plane 8 gfx
  2311.     move.l    a1,a5            ;
  2312.     add.l    #20480,a5        ; a5 = Pointer to plane 8
  2313.     move.l    a1,a3            ; a3 = Pointer to plane 7
  2314.     move.w    #16-1,d7        ; Draw 16 lines
  2315. .copy    move.b    (a2,d0.w),(a3)        ; Write to plane 7
  2316.     move.b    (a2,d1.w),(a5)        ; Write to plane 8
  2317.     add.l    #40,a3            ; Next line in plane 7
  2318.     add.l    #40,a5            ; Next line in plane 8
  2319.     add.l    #64,a2            ; Next line in gfx
  2320.     dbf    d7,.copy        ; Draw next line
  2321.     rts
  2322.     
  2323.  
  2324. ; *****************************************************************************
  2325. ; PPutStr 
  2326. ; -----------------------------------------------------------------------------
  2327. ; Inputs     : a0 = Pointer to null-terminated string
  2328. ;              a1 = Pointer to first bitplane
  2329. ; Output     : -
  2330. ; Description: Planar Put String.
  2331. ; Notes      : -
  2332. ; Scratch    : All
  2333. ; Author     : Matthijs Hollemans
  2334. ; History    : 06 Jan 1997
  2335. ; *****************************************************************************
  2336.  
  2337.     ALIGNLONG
  2338.     
  2339. PPutStr
  2340.     moveq    #0,d0
  2341. .loop    move.b    (a0)+,d0        ; Read next character
  2342.     beq.b    .Done            ; NULL byte ? then we're done
  2343.     bsr.b    PPutChr            ; Write character
  2344.     addq.l    #1,a1            ; Next position on screen
  2345.     bra.b    .loop            ; Next character
  2346. .Done    rts                ; Finished
  2347.  
  2348.  
  2349. ; *****************************************************************************
  2350. ; CPutStr
  2351. ; -----------------------------------------------------------------------------
  2352. ; Inputs     : a0 = Pointer to null-terminated string
  2353. ;           a1 = Pointer to chunky buffer.
  2354. ; Output     : -
  2355. ; Description: Chunky Put String
  2356. ; Notes      : -
  2357. ; Scratch    : d0,d1,d2,d6,d7,a1,a2,a3
  2358. ; Author     : Matthijs Hollemans
  2359. ; History    : 08 Jan 1996
  2360. ; *****************************************************************************
  2361.  
  2362.     ALIGNLONG
  2363.     
  2364. CPutStr
  2365.     moveq    #0,d0
  2366. .loop    move.b    (a0)+,d0        ; Read next character
  2367.     beq.b    .Done            ; NULL byte ? then we're done
  2368.     bsr.b    CPutChr            ; Write character
  2369.     addq.l    #8,a1            ; Next position on screen
  2370.     bra.b    .loop            ; Next character
  2371. .Done    rts                ; Finished
  2372.  
  2373.  
  2374. ; *****************************************************************************
  2375. ; CPutChr
  2376. ; -----------------------------------------------------------------------------
  2377. ; Inputs     : a1   = Pointer to chunky buffer
  2378. ;           d0.l = ASCII character
  2379. ; Output     : -
  2380. ; Description: Chunky Put Character.
  2381. ; Notes      : -
  2382. ; Scratch    : d0,d1,d2,d6,d7,a2,a3
  2383. ; Author     : Matthijs Hollemans
  2384. ; History    : 08 Jan 1996
  2385. ; *****************************************************************************
  2386.  
  2387.     ALIGNLONG
  2388.     
  2389. CPutChr
  2390.     lea    ChunkyFont,a2        ; a2 = Pointer to gfx
  2391.     sub.l    #32,d0            ; Convert ASCII
  2392.     move.l    d0,d1            ;
  2393.     lsl.l    #3,d1            ; d1 = Offset for gfx 
  2394.     add.l    d1,a2            ; a2 += offset
  2395.     move.l    a1,a3            ; a3 = Pointer to chunkybuffer
  2396.     move.w    #7,d6            ; }_ 8x8 character
  2397. .y    move.w    #7,d7            ; }
  2398. .x    move.b    (a2),d2            ; Read gfx byte
  2399.     beq.b    .skip            ; 0 ? Then transparent, skip write
  2400.     move.b    d2,(a3)            ; Write gfx byte 
  2401. .skip    add.l    #1,a3            ; Next pixel in chunky buffer
  2402.     add.l     #1,a2            ; Next pixel in gfx
  2403.     dbf    d7,.x            ; 
  2404.     add.l    #BufferW-8,a3        ; Next row in chunky buffer
  2405.     add.l    #512-8,a2        ; Next row in gfx
  2406.     dbf    d6,.y            ; 
  2407.     rts
  2408.  
  2409.  
  2410. ; *****************************************************************************
  2411. ; CWriteTime, PWriteTime
  2412. ; -----------------------------------------------------------------------------
  2413. ; Inputs     : a4.l = Offset in chunky buffer
  2414. ;           d5.l = Time (in ticks)
  2415. ; Output     : -
  2416. ; Description: CWriteTime: writes time as M:SS in chunky buffer.
  2417. ;              PWriteTime: writes time as M:SS on 2-bitplane screen.
  2418. ; Notes      : -
  2419. ; Scratch    : All
  2420. ; Author     : -
  2421. ; History    : -
  2422. ; *****************************************************************************
  2423.  
  2424. CalcTime
  2425.     divu.w    #50,d5            ; Total secs = Ticks / 50
  2426.     and.l    #$ffff,d5        ; kill remainder
  2427.     divu.w    #60,d5            ; Min = Total secs / 60
  2428.     move.l    d5,d3            ; 
  2429.     and.l    #$f,d5            ; kill remainder
  2430.     swap    d3            ; Sec = Total secs MOD 60
  2431.     and.l    #$ffff,d3        ; kill msw
  2432.     divu    #10,d3            ; 
  2433.     move.l    d3,d4            ;
  2434.     swap    d4            ; Get second
  2435.     and.l    #$f,d3            ;
  2436.     and.l    #$f,d4            ;
  2437.     rts
  2438.  
  2439. CWriteTime
  2440.     bsr.b    CalcTime        ; Calculate time
  2441.     CPUTNUM    d5,a4            ; X:xx
  2442.     addq.l    #8,a4            ;
  2443.     CPUTCHR    #58,a4            ; :
  2444.     addq.l    #8,a4            ;
  2445.     CPUTNUM    d3,a4            ; x:Xx
  2446.     addq.l    #8,a4            ;
  2447.     CPUTNUM    d4,a4            ; x:xX
  2448.     rts
  2449.  
  2450. PWriteTime
  2451.     bsr.w    CalcTime        ; Calculate time
  2452.     PPUTNUM    d5,a4            ; X:xx
  2453.     addq.l    #1,a4            ;
  2454.     PPUTCHR    #58,a4            ; :
  2455.     addq.l    #1,a4            ;
  2456.     PPUTNUM    d3,a4            ; x:Xx
  2457.     addq.l    #1,a4            ;
  2458.     PPUTNUM    d4,a4            ; x:xX
  2459.     rts
  2460.  
  2461.     
  2462. ; *****************************************************************************
  2463. ; SetPal24
  2464. ; -----------------------------------------------------------------------------
  2465. ; Inputs     : a0 = Pointer to coplist colors
  2466. ;              a1 = Palette
  2467. ; Output     : -
  2468. ; Description: Copies a 24-bit 256-colour palette into a coplist.
  2469. ; Notes      : Palette has to be ordered like this:
  2470. ;              $00RrGgBb,$00RrGgBb,...,$00RrGgBb
  2471. ; Scratch    : d6,d7,a0,a1
  2472. ; Author     : Matthijs Hollemans
  2473. ; History    : 4 Jan 1996
  2474. ; *****************************************************************************
  2475.  
  2476.     ALIGNLONG
  2477.     
  2478. SetPal24
  2479.     add.l    #6,a0            ; 
  2480.     move.w    #8-1,d6            ; Set 8 banks
  2481. .loop0  move.w    #32-1,d7        ; Set 32 colour registers
  2482.  
  2483. .loop1    move.l    (a1)+,d0        ; d0 = 00RrGgBb
  2484.     move.w    d0,d1            ; d1 = GgBb
  2485.     lsr.w    #8,d1            ; d1 = 00Gg
  2486.     and.w    #$f0,d1            ; d1 = 00G0
  2487.     move.w    d0,d2            ; d2 = GgBb
  2488.     and.w    #$f0,d2            ; d2 = 00B0
  2489.     lsr.w    #4,d2            ; d2 = 000B
  2490.     or.w    d1,d2            ; d2 = 00GB
  2491.     move.l    d0,d1            ; d1 = 00RrGgBb
  2492.     swap    d1            ; d1 = GgBb00Rr
  2493.     and.w    #$f0,d1            ; d1 = 00R0
  2494.     lsl.w    #4,d1            ; d1 = 0R00
  2495.     or.w    d1,d2            ; d2 = 0RGB
  2496.  
  2497.     move.w    d2,(a0)            ; Write high 12-bits in copperlist
  2498.     
  2499.     move.w    d0,d1            ; d1 = GgBb
  2500.     and.w    #$f00,d1        ; d1 = 0g00
  2501.     lsr.w    #4,d1            ; d1 = 00g0
  2502.     move.w    d0,d2            ; d2 = GgBb
  2503.     and.w    #$f,d2            ; d2 = 000b
  2504.     or.w    d1,d2            ; d2 = 00gb
  2505.     swap    d0            ; d0 = GgBb00Rr
  2506.     and.w    #$f,d0            ; d0 = 000r
  2507.     lsl.w    #8,d0            ; d0 = 0r00
  2508.     or.w    d0,d2            ; d2 = 0rgb
  2509.  
  2510.     move.w    d2,132(a0)        ; Write low 12-bits in copperlist
  2511.     
  2512.     add.l    #4,a0            ; Next colour
  2513.     dbf    d7,.loop1        ; 
  2514.     add.l    #128+4+4,a0        ; 
  2515.     dbf    d6,.loop0        ;
  2516.     rts                ;
  2517.  
  2518.  
  2519. ; *****************************************************************************
  2520. ; CopyPal24
  2521. ; -----------------------------------------------------------------------------
  2522. ; Inputs     : a0 = Source palette
  2523. ;              a1 = Destination palette
  2524. ; Output     : -
  2525. ; Description: Copies 24-bit source palette into 24-bit destination palette.
  2526. ; Notes      : - 
  2527. ; Scratch    : All
  2528. ; Author     : Matthijs Hollemans
  2529. ; History    : 23 Jan 1997
  2530. ; *****************************************************************************
  2531.  
  2532. CopyPal24
  2533.     move.l    #256-1,d7        ; 256 colours
  2534. .loop    move.l    (a0)+,(a1)+        ; Copy 24-bit colour 
  2535.     dbf    d7,.loop        ;
  2536.     rts                
  2537.  
  2538.  
  2539. ; *****************************************************************************
  2540. ; InitXFade 
  2541. ; -----------------------------------------------------------------------------
  2542. ; Inputs     : d0.b = Stepsize (positive value)
  2543. ; Output     : -
  2544. ; Description: Initialises XFade.
  2545. ; Notes      : Call once before calling XFade.
  2546. ; Scratch    : -
  2547. ; Author     : Matthijs Hollemans
  2548. ; History    : 23 Jan 1997
  2549. ; *****************************************************************************
  2550.  
  2551. InitXFade
  2552.     and.l    #$ff,d0            ; Extend d0 to long (unsigned)
  2553.     move.b    d0,XFadeStep        ; XFadeStep = Stepsize
  2554.     move.l    #$ff,d1            ;
  2555.     divu.w    d0,d1            ; XFadeCount = 255 / Stepsize
  2556.     move.w    d1,XFadeCount        ;
  2557.     rts
  2558.  
  2559.  
  2560. ; *****************************************************************************
  2561. ; XFade 
  2562. ; -----------------------------------------------------------------------------
  2563. ; Inputs     : a0 = Source palette
  2564. ;              a1 = Destination palette
  2565. ; Output     : -
  2566. ; Description: Fades 24-bit source palette to 24-bit destination palette. 
  2567. ; Notes      : If XFadeCount is negative, then fading is ready and the
  2568. ;              routine exits. Start a new fade by calling InitXFade.
  2569. ; Scratch    : All
  2570. ; Author     : Matthijs Hollemans
  2571. ; History    : 23 Jan 1997
  2572. ; *****************************************************************************
  2573.  
  2574.     ALIGNLONG
  2575.     
  2576. XFade
  2577.     tst.w    XFadeCount        ; IF XFadeCount < 0
  2578.     bmi.b    .Done            ; THEN xfade is ready
  2579.  
  2580.     move.b    XFadeStep,d3        ; d3 = Step
  2581.     ext.w    d3            ; Extend d3 to word size !
  2582.     move.b    d3,d4            ;
  2583.     neg.b    d4            ; d4 = -Step
  2584.     ext.w    d4            ; Extend d4 to word size !
  2585.     move.l    #256-1,d7        ; Process 256 colours
  2586. .loop    addq.l    #1,a0            ; }_ Skip first byte
  2587.     addq.l    #1,a1            ; }
  2588.     moveq    #3-1,d6            ; Loop 3 times (r,g and b)
  2589. .rgb    moveq    #0,d0            ; }_ Clear registers
  2590.     move.l    d0,d2            ; }
  2591.     move.b    (a0),d0            ; d0 = Source component
  2592.     move.b    (a1)+,d1        ; d1 = Dest component
  2593.     move.b    d1,d2            ;
  2594.     sub.w    d0,d2            ; d2 = Dest-Source (word!!!)
  2595.     cmp.w    d3,d2            ; IF d2 > Step
  2596.     ble.b    .0            ;
  2597.     add.b    d3,d0            ;   Source += Step
  2598.     bra.b    .write            ;
  2599. .0    cmp.w    d4,d2            ; ELSEIF d2 < -Step
  2600.     bge.b    .1            ;
  2601.     sub.b    d3,d0            ;   Source -= Step
  2602.     bra.b    .write            ;
  2603. .1    move.b    d1,d0            ; ELSE Source = Dest
  2604. .write    move.b    d0,(a0)+        ; Write new source component
  2605.     dbf    d6,.rgb            ;
  2606.     dbf    d7,.loop        ;
  2607.     sub.w    #1,XFadeCount        ; XFadeCount -= 1
  2608. .Done                    ;
  2609.     rts                ;
  2610.  
  2611. XFadeCount    dc.w    0
  2612. XFadeStep    dc.b    0
  2613.  
  2614.  
  2615. ; *****************************************************************************
  2616. ; GetJoy1
  2617. ; -----------------------------------------------------------------------------
  2618. ; Inputs     : -
  2619. ; Outputs    : -
  2620. ; Description: Reads position of joystick 1.
  2621. ; Notes      : Results in Joy1Up, Joy1Down, Joy1Left, Joy1Right, Joy1Fire.
  2622. ; Scratch    : -
  2623. ; Author     : Matthijs Hollemans
  2624. ; History    : 24 Dec 1996
  2625. ; *****************************************************************************
  2626.  
  2627.     ALIGNLONG
  2628.     
  2629. GetJoy1    movem.l    d0/d1,-(sp)
  2630.     move.w    $dff00c,d0        ; JOY1DAT
  2631.     btst    #1,d0
  2632.     sne    Joy1Right
  2633.     btst    #9,d0
  2634.     sne    Joy1Left
  2635.     move.w    d0,d1
  2636.     lsr.w    #1,d1
  2637.     eor.w    d0,d1
  2638.     btst    #0,d1
  2639.     sne    Joy1Down
  2640.     btst    #8,d1
  2641.     sne    Joy1Up
  2642.     moveq    #0,d0
  2643.     btst.b    #7,$bfe001        ; CIA-A PRA
  2644.     seq    Joy1Fire
  2645.     movem.l    (sp)+,d0/d1
  2646.     rts
  2647.  
  2648.  
  2649. ; *****************************************************************************
  2650. ; WaitVBL
  2651. ; -----------------------------------------------------------------------------
  2652. ; Inputs     : -
  2653. ; Output     : -
  2654. ; Description: Waits for vertical blank.
  2655. ; Notes      : -
  2656. ; Scratch    : None
  2657. ; Author     : -
  2658. ; History    : -
  2659. ; *****************************************************************************
  2660.  
  2661.     ALIGNLONG
  2662.     
  2663. WaitVBL    move.l    d0,-(sp)
  2664.     move.b    $bfe801,d0
  2665. .wait    cmp.b    $bfe801,d0
  2666.     beq.b    .wait
  2667.     move.l    (sp)+,d0
  2668.     rts
  2669.  
  2670.  
  2671. ; *****************************************************************************
  2672. ; GetKey 
  2673. ; -----------------------------------------------------------------------------
  2674. ; Inputs     : -
  2675. ; Output     : KeyState and KeyRaw
  2676. ; Description: Gets keyboard input
  2677. ; Notes      : -
  2678. ; Scratch    : d0,d1
  2679. ; Author     : Fabio Bizetti
  2680. ; History    : 11 Jan 1997, modified by Matthijs Hollemans
  2681. ; *****************************************************************************
  2682.  
  2683. GetKey
  2684.     move.w    $dff01c,d1        ; Save INTENA
  2685.         or.w     #$c000,d1        ; 
  2686.      move.w    #$7fff,$dff09a        ; Disable all interrupts
  2687.  
  2688.     moveq    #0,d0            ;
  2689.      move.b    $bfec01,d0        ; Get byte from CIA-A serial port
  2690.      
  2691.      bset.b    #6,$bfee01        ; Set serial port to output
  2692.      move.b    #$40,$bfe401        ; }_ CIA-A TimerA = 64
  2693.      move.b    #$00,$bfe501        ; }
  2694.      move.b    #$51,$bfee01        ; Handshake
  2695.      tst.b    $bfed01            ;
  2696.      tst.b    $bfed01            ;
  2697. .Wait    btst.b    #0,$bfed01        ; }_ Wait for TimerA to finish
  2698.      beq.b    .Wait            ; }
  2699.      bclr.b    #6,$bfee01        ; Set serial port to input
  2700.      
  2701.      not.b    d0            ; Datalines are low active
  2702.      ror.b    #1,d0            ; Bits are sent as 6-5-4-3-2-1-0-7
  2703.      bpl.b    .Down            ; IF Key was released
  2704.      move.b    #KEY_NONE,KeyState    ;   KeyState = KEY_NONE
  2705.      move.b    d0,KeyRaw        ;   KeyRaw = new key with bit 7 set!
  2706.     bra.b    .Done            ; ENDIF
  2707. .Down    cmp.b    KeyRaw,d0        ; IF old key == new key 
  2708.     bne.b    .New            ;
  2709.     move.b    #KEY_REPEAT,KeyState    ;   KeyState = KEY_REPEAT
  2710.     bra.b    .Done            ; ENDIF
  2711. .New     move.b    d0,KeyRaw        ; KeyRaw = new key
  2712.     move.b    #KEY_NEW,KeyState    ; KeyState = KEY_NEW
  2713.      
  2714. .Done    move.w    d1,$dff09a        ; Restore interrupts
  2715.     rts                ;
  2716.  
  2717.  
  2718. ; *****************************************************************************
  2719. ; GetStr
  2720. ; -----------------------------------------------------------------------------
  2721. ; Inputs     : -
  2722. ; Output     : -
  2723. ; Description: Gets string input from user and stores it in Plyr_Name.
  2724. ; Notes      : Could rewrite this to be somewhat more universal, but then
  2725. ;              again, why bother ;)
  2726. ; Scratch    : -
  2727. ; Author     : Matthijs Hollemans
  2728. ; History    : 21 Jan 1997
  2729. ; *****************************************************************************
  2730.  
  2731. GetStr
  2732.     movem.l    d0-d7/a0-a6,-(sp)    ; Save registers
  2733.     
  2734.     lea    Plyr_Name,a0        ; Destination address
  2735.     move.l    a0,a1            ; Store pointer
  2736.     lea    Raw2ASCII,a2        ; Translation table
  2737.     move.b    #0,d7            ; Size = 0
  2738.     move.l    #388*40+25,d6        ; Start position on screen
  2739.     PPUTCHR    #94,d6            ; Write cursor
  2740.  
  2741. .loop    bsr.w    WaitVBL            ; REPEAT
  2742.     bsr.w    GetKey            ;   Read key
  2743.     cmp.b    #KEY_NEW,KeyState    ; 
  2744.     bne.b    .loop            ; UNTIL KeyState = KEY_NEW
  2745.     
  2746.     cmp.b    #KEY_ENTER,KeyRaw    ; IF KeyRaw = KEY_ENTER
  2747.     bne.b    .noent            ;
  2748.     move.b    #0,(a1)            ;   Add NULL-character to end of string
  2749.     bra.w    .Done            ;   Finished
  2750. .noent  cmp.b    #KEY_ESC,KeyRaw        ; ELSEIF KeyRaw = KEY_ESC
  2751.     bne.b    .noesc            ;
  2752.     move.b    #0,(a0)            ;   NULL-character at start of string
  2753.     bra.w    .Done            ;   Finished
  2754. .noesc    cmp.b    #KEY_BACKSPACE,KeyRaw    ; ELSEIF KeyRaw = KEY_BACKSPACE
  2755.     bne.b    .nobs            ;
  2756.     tst.b    d7            ;   IF Size > 0
  2757.     ble.b    .endif            ; 
  2758.     subq.b    #1,d7            ;     Size -= 1
  2759.     subq.b    #1,d6            ;     Position -= 1
  2760.     subq.l    #1,a1            ;     Decrease string pointer
  2761.     bra.b    .endif            ;   ENDIF
  2762. .nobs    cmp.b    #$40,KeyRaw        ; ELSEIF (KeyRaw <= $40)
  2763.     bgt.b    .endif            ;
  2764.     cmp.b    #$10,KeyRaw        ;        AND (KeyRaw >= $10)
  2765.     blt.b    .endif            ;
  2766.     cmp.b    #MaxStrLen,d7        ;   IF Size = MaxStrLen
  2767.     bge.b    .endif            ;   THEN skip this part
  2768.     moveq    #0,d1            ;
  2769.     move.b    KeyRaw,d1        ;   Convert Raw to ASCII
  2770.     move.b    (a2,d1.w),d1        ;   
  2771.     beq.b    .endif            ;   IF ASCII=0 THEN illegal key
  2772.     move.b  d1,(a1)+        ;   Write ASCII value in string
  2773.     PPUTCHR    d1,d6            ;   Write ASCII value on screen
  2774.     addq.b    #1,d7            ;   Size += 1    
  2775.     addq.b    #1,d6            ;   Position += 1
  2776. .endif    move.l    d6,d5            ; ENDIF
  2777.     PPUTCHR    #94,d5            ; Write cursor
  2778.     add.l    #1,d5            ;
  2779.     PPUTCHR    #32,d5            ; Write empty space behind cursor
  2780.     PPUTCHR    #95,#389*40-3        ; Restore frame ;)
  2781.     bra.w    .loop            ;
  2782. .Done                    ; Finished
  2783.     movem.l    (sp)+,d0-d7/a0-a6    ; Restore registers
  2784.     rts                ;
  2785.  
  2786.  
  2787. ; =============================================================================
  2788. ;
  2789. ;                           B L I T T E R S C R E E N
  2790. ;
  2791. ; =============================================================================
  2792.  
  2793.     ALIGNLONG
  2794.     
  2795. timer         dc.l     0       ; some vbl-timers...
  2796. timer2         dc.l     0
  2797. oldtimer     dc.l     0
  2798.  
  2799. show2         equ     0    ; equ 1 show rastertiming of blitterpasses
  2800.  
  2801. ; *****************************************************************************
  2802. ; Macro's
  2803. ; *****************************************************************************
  2804.  
  2805. waitblt MACRO                ; Hardware WaitBlit()
  2806.        btst #6,$dff002         ; Old blitters said to have bug...
  2807. waitblt\@:                ;
  2808.        btst #6,$dff002            ;
  2809.        bne waitblt\@            ;
  2810.       ENDM                ;
  2811.  
  2812. ; *****************************************************************************
  2813. ; mkbltscr
  2814. ; -----------------------------------------------------------------------------
  2815. ; Inputs     : a0 = Copperlist
  2816. ;              a1 = Screen
  2817. ; Output     :
  2818. ; Description: Makes copperlist for blitterscreen.
  2819. ; Notes      : -
  2820. ; History    : ??.??.1995, Jurgen "Rally" Fischer
  2821. ;              26.12.1996, Matthijs Hollemans
  2822. ; *****************************************************************************
  2823.  
  2824.     ALIGNLONG
  2825.     
  2826. mkbltscr:
  2827.     ; Write bitplane pointers in copperlist header ------------------------
  2828.  
  2829.     move.l    #CopBpl,a2        ; a2=Position in copperlist header
  2830.     move.l    a1,d0            ; d0=Screen address
  2831.        move.w     #8-1,d7            ; Write 8 bitplanes
  2832. .mkbpl    swap    d0            ;
  2833.     move.w    d0,2(a2)        ;
  2834.     swap    d0            ;
  2835.     move.w    d0,6(a2)        ;
  2836.     addq.l    #8,a2            ; Next position in copperlist
  2837.     add.l    #320*128/8,d0        ; Next bitplane
  2838.     dbf    d7,.mkbpl        ;
  2839.  
  2840.     ; Copy copperlist header into chipmem ---------------------------------
  2841.  
  2842.     move.l    #Cop,a2            ;
  2843.     move.w    #CopEnd-Cop-1,d7    ;
  2844. .cpycop    move.b    (a2)+,(a0)+        ;
  2845.     dbf    d7,.cpycop        ;
  2846.         
  2847.     ; 2xY stuff -----------------------------------------------------------
  2848.  
  2849.        move.l     chipmem,a2         ;
  2850.      add.l     #sprbuf,a2        ; a2=Sprite buffer
  2851.        move.l     a1,d0           ; d0=Screen 
  2852.       move.l     #40,d2             ; YStart 
  2853.        move.l     #128,d3         ; Number of lines 
  2854.        move.l     #40*128,d4         ; Planesize (in bytes)
  2855.        move.l     #40,d5             ; Linesize (in bytes)
  2856.        jsr     mk2xY            ;
  2857.  
  2858.     ; End copperlist (feel free to add your own copper stuff) ------------
  2859.  
  2860.        move.l     #$fffffffe,(a0)+    
  2861.        rts
  2862.  
  2863.  
  2864. ; ****************************************************************************
  2865. ; int3
  2866. ; ----------------------------------------------------------------------------
  2867. ; Hardware-hack interrupt handler
  2868. ; ****************************************************************************
  2869.  
  2870.     ALIGNLONG
  2871.     
  2872. int3:
  2873.        btst     #6,$dff01f        ; BLIT3 set ?
  2874.        beq.b     nobltint        ; Nope, interrupt not caused by blitter
  2875.                        
  2876. bltint:
  2877.        move.w     #$0040,$dff09c        ; Clear BLIT3 
  2878.  
  2879.        movem.l d0-d1/a5/a6,-(sp)
  2880.        move.l     #$dff000,a5
  2881.        move.l     bltpc(pc),a6        ; a6 = "program counter" for blitlist
  2882.  
  2883.        IFNE     show2
  2884.        move.w     #$0ff,$dff180          ;blt reload
  2885.        ENDC
  2886.  
  2887. bltsetreg:
  2888.        move.l     (a6)+,d0
  2889.        move.w     d0,d1 
  2890.      beq.b     bltintend 
  2891.      swap     d0
  2892.        move.w     d0,0(a5,d1.w)
  2893.  
  2894.        cmp.w     #$5e,d1 
  2895.     beq.b     bltstarted
  2896.        cmp.w     #$58,d1 
  2897.      bne.b     bltsetreg
  2898. * ---
  2899. bltstarted:
  2900.        move.l a6,bltpc
  2901.        movem.l (sp)+,d0-d1/a5/a6
  2902.  
  2903.        IFNE show2
  2904.        move.w #$800,$dff180  ;blt works
  2905.        ENDC
  2906.        rte
  2907.  
  2908. bltintend:
  2909.        clr.w bltbsy
  2910.        movem.l (sp)+,d0-d1/a5/a6
  2911.  
  2912.        IFNE show2
  2913.        move.w #$000,$dff180 ;blt rdy
  2914.        ENDC
  2915.        rte
  2916.  
  2917. nobltint:                ; No blitter interrupt
  2918.        btst #5,$dff01f            ; Was it a VBL interrupt?
  2919.        bne.b vblint
  2920.        btst #4,$dff01f            ; Or a copper interrupt ?
  2921.       bne.b copint
  2922. * huh ?                    ; Fuckup !
  2923.        move.w #$3fff,$dff09c         ; kill all requests to avoid(?) delirium
  2924.        rte
  2925.  
  2926.     ALIGNLONG
  2927.     
  2928. bltpc     dc.l 0  ;pointer to blitterinstructions to be done
  2929. bltbsy     dc.w 0     ;this is 0 if all blitter-passes are done
  2930.  
  2931.     ALIGNLONG
  2932.     
  2933. vblint:
  2934.        move.w     #$0020,$dff09c        ; remove vblank interrupt
  2935.        movem.l d0-d7/a0-a6,-(sp)
  2936.  
  2937.        move.l     customvbl,a0 
  2938.      jsr     (a0)             ; CUSTOM ROUTINE HERE!
  2939.  
  2940.        add.l     #1,timer 
  2941.     add.l     #1,timer2
  2942.  
  2943.        move.w     #$0020,$dff09c
  2944.        movem.l (sp)+,d0-d7/a0-a6
  2945.        rte
  2946.  
  2947. copint: ;theoretically you never get here... copints are disabled ;)
  2948.        move.w #$0010,$dff09c        ; remove copper interrupt
  2949.        rte
  2950.  
  2951. customvbl     dc.l MyVBLHandler    ; Pointer to custom vblank routine
  2952.  
  2953.  
  2954. ; *****************************************************************************
  2955. ; mk2xY
  2956. ; -----------------------------------------------------------------------------
  2957. ; Inputs     : a0   = Copperlist
  2958. ;              a2   = Sprite Buffer (size = 312*4*2*8)
  2959. ;              d0.l = Plane0
  2960. ;              d2   = Ystart
  2961. ;              d3   = Number of lines (0-127)
  2962. ;              d4.l = Planesize
  2963. ;              d5   = Linesize
  2964. ; Output     : -
  2965. ; Description: Make a special 2x2 or 2x1 screen, needed for c2bs.
  2966. ; Notes      : All buffers in CHIP mem.
  2967. ;              2x2 or 2x1 depends on modulo/doublescan-bit in coplist header.
  2968. ;              Make sure sprites are 64-bit (fmode 3), highest priority and
  2969. ;              choose the spritebank that has got a dark color at offset 1
  2970. ;              (eg. col 1, 17, 33, ...).
  2971. ; History    : 1995, Jurgen "Rally" Fischer
  2972. ; *****************************************************************************
  2973.  
  2974.     ALIGNLONG
  2975.     
  2976. mfpoffs     dc.l 0 ;not used by caller
  2977. mfloffs     dc.l 0
  2978.  
  2979. mk2xY:
  2980.        jsr     mspr     ;gen cover-sprites in (a2)+ and copmoves in (a0)+
  2981.  
  2982. * PLANES
  2983.        movem.l d0-d7/a1-a6,-(sp)     ;a0=(ptr)copl
  2984.  
  2985.        move.l     d4,mfpoffs 
  2986.      ext.l     d5 
  2987.      move.l     d5,mfloffs
  2988.  
  2989. * gen planeptr moves
  2990.        movem.l d3/d0,-(sp)
  2991.        move.w     #$00e0,d3 
  2992.      move.w     #4-1,d7
  2993. mf256genhi:
  2994.        move.w     d3,(a0)+ 
  2995.     addq.w     #2,d3 
  2996.      move.l     d0,(a0)+  ;store hiwd ! -2(a0)
  2997.        move.w     d3,-2(a0) 
  2998.      addq.w     #2,d3 
  2999.      move.w     d0,(a0)+ ;store lowd
  3000. ;every 2nd plane same data
  3001.        move.w     d3,(a0)+ 
  3002.      addq.w     #2,d3 
  3003.      move.l     d0,(a0)+  ;store hiwd ! -2(a0)
  3004.        move.w     d3,-2(a0) 
  3005.      addq.w     #2,d3 
  3006.      move.w     d0,(a0)+ ;store lowd
  3007.  
  3008.        add.l     mfpoffs,d0
  3009.        dbra     d7,mf256genhi
  3010. * end gen ptrs
  3011.        movem.l (sp)+,d3/d0
  3012.  
  3013.        and.l     #$ff,d2 
  3014.      sub.b     #1,d2 
  3015.      ror.l     #8,d2   ;sub #1: prev line
  3016.        move.l     #$00e1fffe,d4 
  3017.      or.l     d2,d4           ;WAS: 00df
  3018. *
  3019.        move.w     d3,d5
  3020.        subq.w     #1,d5
  3021. mf256yanz:
  3022.        move.l     #$1020010,d7
  3023.       move.w     #2-1,d6
  3024. mf256do2:
  3025.        move.l     d4,(a0)+ 
  3026.      add.l     #$01000000,d4  ;cwait
  3027.        move.l     d7,(a0)+ 
  3028.      eor.l     #$00000031,d7  ;horiz shift
  3029.                      ;             ^---- 3: 1 -> 2 -> 1 -> 2 ....
  3030.        dbra     d6,mf256do2
  3031.  
  3032.        add.l     mfloffs,d0
  3033.        dbra     d5,mf256yanz
  3034.  
  3035.        movem.l (sp)+,d0-d7/a1-a6 ;a0=(ptr)copl
  3036.        rts
  3037.  
  3038.  
  3039. ; ****************************************************************************
  3040. ; mspr
  3041. ; ----------------------------------------------------------------------------
  3042. ; Inputs     : a0 = Copperlist
  3043. ;              a2 = Sprite Buffer (coplist: FMODE=$F, $dff104=$003f)
  3044. ; Output     : -
  3045. ; Description: Sprites that mask out doubleplane-data-rubbish.
  3046. ; Notes      : mksprites into sprbuf=(a2)+ and according coppermoves in (a0)+
  3047. ; History    : 1995, Jurgen "Rally" Fischer.
  3048. ; ***************************************************************************
  3049.  
  3050.     ALIGNLONG
  3051.     
  3052. mspr:
  3053.        movem.l d0-d7/a1-a6,-(sp) ;no a0! coz *copl
  3054.  
  3055.        move.l     #$00968020,(a0)+ ;rehash sprites (for safety)
  3056.  
  3057.        lea     mf2sprdat,a1
  3058.  
  3059.        move.l     a2,d0
  3060.        add.l     #15,d0
  3061.        and.l     #$fffffff0,d0
  3062.       move.l     d0,a2 ;align
  3063.  
  3064.        move.w     #$0120,d1 ;spr0pth
  3065.     
  3066.        move.w     #8-1,d7 ;sprcnt
  3067. mf2mkspr:
  3068. * cmoves for sprptr in copl
  3069.  
  3070.        move.l     a2,d0
  3071.       move.w     d1,(a0)+
  3072.        addq.w     #2,d1 ;hiptr -> loptr
  3073.        swap     d0
  3074.        move.w     d0,(a0)+
  3075.        swap     d0 ;hiwd
  3076.        move.w     d1,(a0)+
  3077.        addq.w    #2,d1 ;next sprptr
  3078.        move.w     d0,(a0)+
  3079.  
  3080. * make sprbuf
  3081.        move.l     (a1)+,(a2)+ ;ctl1
  3082.        move.l     #0,(a2)+    ;dummy for 64bit fetchmode
  3083.        move.l     (a1)+,(a2)+ ;ctl2
  3084.        move.l     #0,(a2)+    ;dummy for 64bit fetchmode
  3085.  
  3086.        move.l     (a1)+,d2
  3087.        move.l     (a1)+,d3
  3088.        move.l     d2,d4
  3089.        ror.l     #1,d4
  3090.       move.l     d3,d5
  3091.        ror.l     #1,d5
  3092.  
  3093.        move.w #128-1,d6
  3094. mf2mksprdat:
  3095.        move.l d2,(a2)+
  3096.        move.l d2,(a2)+
  3097.        move.l d3,(a2)+
  3098.        move.l d3,(a2)+
  3099. ;2nd line
  3100.        move.l d4,(a2)+
  3101.        move.l d4,(a2)+
  3102.        move.l d5,(a2)+
  3103.        move.l d5,(a2)+                ;2nd plane
  3104.  
  3105.        dbra d6,mf2mksprdat
  3106.  
  3107.     move.l #$0,(a2)+
  3108.        move.l #$0,(a2)+
  3109.       move.l #$0,(a2)+
  3110.        move.l #$0,(a2)+
  3111.  
  3112.        dbra d7,mf2mkspr
  3113.  
  3114.        movem.l (sp)+,d0-d7/a1-a6 ;ohne a0! weil *copl
  3115.        rts
  3116.  
  3117. * ctl 1, ctl 2, plane 0, plane 1 (to be lsr'd for 2nd line)
  3118. mf2sprdat:
  3119.        dc.l $28400000,$a7020000,$aaaaaaaa,$00000000
  3120.        dc.l $28600000,$a7020000,$aaaaaaaa,$00000000 ;1 & 2 nonattached, col 1 :)
  3121.        dc.l $28800000,$a7020000,$aaaaaaaa,$00000000
  3122.        dc.l $28800000,$a7820000,$00000000,$00000000
  3123.        dc.l $28a00000,$a7020000,$aaaaaaaa,$00000000
  3124.        dc.l $28a00000,$a7820000,$00000000,$00000000
  3125.        dc.l $28c00000,$a7020000,$aaaaaaaa,$00000000
  3126.        dc.l $28c00000,$a7820000,$00000000,$00000000
  3127.  
  3128.  
  3129. ; ****************************************************************************
  3130. ; c2bs
  3131. ; ----------------------------------------------------------------------------
  3132. ; Inputs     : a0   = Chunky Buffer
  3133. ;              a1   = Screen
  3134. ;              a2   = Pass Buffer (half size of chunky buffer)
  3135. ;              a3   = Scramble Buffer (at size of chunky buffer)
  3136. ;              a6   = Blitter-list Buffer (size less than 2k)
  3137. ;              d0.l = Number of chunky pixels
  3138. ;              d1.l = Plane Offset (number of bytes between planes)
  3139. ; Outputs    : -
  3140. ; Description: Non-scrambled chunky-to-planar conversion. 
  3141. ;              Not really C2P, destination is special 2x2 or 2x1 screen.
  3142. ; Notes      : All buffers in CHIP memory, except Blitter-list (a6).
  3143. ; History    : 1995, Jurgen "Rally" Fischer.
  3144. ; ****************************************************************************
  3145.  
  3146.     ALIGNLONG
  3147.     
  3148. c2bs:
  3149.  
  3150.        tst.w     bltbsy 
  3151.     bne.b     c2bs         ;for the very unlikely case your mapping-
  3152.                                ;engine renders faster than blitterc2p ;)
  3153.                                                       
  3154.        move.l     a6,bltpc     ;handler starts at bltpc
  3155.  
  3156.        movem.l d0-d1/a0-a3,-(sp)
  3157.        move.l     a3,a4 ;well....
  3158.  
  3159. *** init values
  3160.  
  3161.        move.l     #$04000096,(a6)+
  3162.       move.l     #$80400096,(a6)+
  3163.  
  3164.        move.l     #$ffff0044,(a6)+
  3165.        move.l     #$ffff0046,(a6)+
  3166.  
  3167. *** scrambling passes
  3168. ;subpass 1
  3169.       lea     (a0),a3
  3170.        move.l     a3,(a6)+ 
  3171.      move.w     #$004c,-2(a6) ;B
  3172.        move.w     a3,(a6)+ 
  3173.      move.w     #$004e,(a6)+
  3174.       lea     4(a0),a3
  3175.        move.l     a3,(a6)+ 
  3176.      move.w     #$0050,-2(a6) ;A
  3177.        move.w     a3,(a6)+ 
  3178.      move.w     #$0052,(a6)+
  3179.       lea     (a4),a3
  3180.       move.l     a3,(a6)+ 
  3181.      move.w    #$0054,-2(a6) ;D
  3182.        move.w     a3,(a6)+ 
  3183.      move.w     #$0056,(a6)+
  3184.  
  3185.        move.l #$8de40040,(a6)+
  3186.        move.l #$00000042,(a6)+
  3187.        move.l #$00ff0070,(a6)+ ;cdat
  3188.  
  3189.        move.l #$00060064,(a6)+ 
  3190.      move.l #$00060062,(a6)+ ;a/b mod
  3191.        move.l #$00060066,(a6)+ ;d mod
  3192.  
  3193.        move.l d0,d6 
  3194.     lsr.l #3,d6 ;1/4 of scr, words => /8
  3195.        move.w d6,(a6)+
  3196.        move.w #$5C,(a6)+       ;SIZV
  3197.  
  3198.        move.l #$0001005E,(a6)+ ;SIZH+start
  3199.  
  3200. ;subpass2
  3201.       lea 2(a0),a3
  3202.        move.l a3,(a6)+ 
  3203.      move.w #$004c,-2(a6) ;B
  3204.        move.w a3,(a6)+ 
  3205.      move.w #$004e,(a6)+
  3206.       lea 6(a0),a3
  3207.       move.l a3,(a6)+ 
  3208.      move.w #$0050,-2(a6) ;A
  3209.        move.w a3,(a6)+ 
  3210.     move.w #$0052,(a6)+
  3211.       lea 2(a4),a3
  3212.        move.l a3,(a6)+ 
  3213.     move.w #$0054,-2(a6) ;D
  3214.        move.w a3,(a6)+ 
  3215.      move.w #$0056,(a6)+
  3216.  
  3217.      move.l #$8de40040,(a6)+
  3218.        move.l #$00000042,(a6)+
  3219.       move.l #$00ff0070,(a6)+ ;cdat
  3220.  
  3221.        move.l #$00060064,(a6)+ 
  3222.      move.l #$00060062,(a6)+ ;a/b mod
  3223.        move.l #$00060066,(a6)+ ;d mod
  3224.  
  3225.        move.l d0,d6 
  3226.      lsr.l #3,d6 ;1/4 of scr, words => /8
  3227.        move.w d6,(a6)+
  3228.        move.w #$5C,(a6)+       ;SIZV
  3229.  
  3230.        move.l #$0001005E,(a6)+ ;SIZH+start
  3231.  
  3232. ;subpass 3
  3233.       lea -4(a0,d0.l),a3
  3234.        move.l a3,(a6)+ 
  3235.      move.w #$004c,-2(a6) ;B
  3236.        move.w a3,(a6)+ 
  3237.      move.w #$004e,(a6)+
  3238.       lea -8(a0,d0.l),a3
  3239.        move.l a3,(a6)+ 
  3240.      move.w #$0050,-2(a6) ;A
  3241.        move.w a3,(a6)+ 
  3242.      move.w #$0052,(a6)+
  3243.       lea -4(a4,d0.l),a3
  3244.        move.l a3,(a6)+ 
  3245.      move.w #$0054,-2(a6) ;D
  3246.       move.w a3,(a6)+ 
  3247.      move.w #$0056,(a6)+
  3248.  
  3249.        move.l #$8de40040,(a6)+
  3250.        move.l #$00020042,(a6)+
  3251.        move.l #$ff000070,(a6)+ ;cdat
  3252.  
  3253.        move.l #$00060064,(a6)+ 
  3254.     move.l #$00060062,(a6)+ ;a/b mod
  3255.        move.l #$00060066,(a6)+ ;d mod
  3256.  
  3257.        move.l d0,d6 
  3258.      lsr.l #3,d6 ;1/4 of scr, words => /8
  3259.       move.w d6,(a6)+
  3260.        move.w #$5C,(a6)+       ;SIZV
  3261.  
  3262.        move.l #$0001005E,(a6)+ ;SIZH+start
  3263.  
  3264. ;subpass 4
  3265.       lea -2(a0,d0.l),a3
  3266.        move.l a3,(a6)+ 
  3267.     move.w #$004c,-2(a6) ;B
  3268.        move.w a3,(a6)+ 
  3269.      move.w #$004e,(a6)+
  3270.       lea -6(a0,d0.l),a3
  3271.        move.l a3,(a6)+ 
  3272.      move.w #$0050,-2(a6) ;A
  3273.        move.w a3,(a6)+ 
  3274.      move.w #$0052,(a6)+
  3275.       lea -2(a4,d0.l),a3
  3276.        move.l a3,(a6)+ 
  3277.      move.w #$0054,-2(a6) ;D
  3278.        move.w a3,(a6)+ 
  3279.      move.w #$0056,(a6)+
  3280.  
  3281.        move.l #$8de40040,(a6)+
  3282.        move.l #$00020042,(a6)+
  3283.        move.l #$ff000070,(a6)+ ;cdat
  3284.  
  3285.        move.l #$00060064,(a6)+ 
  3286.     move.l #$00060062,(a6)+ ;a/b mod
  3287.        move.l #$00060066,(a6)+ ;d mod
  3288.  
  3289.        move.l d0,d6 
  3290.     lsr.l #3,d6 ;1/4 of scr, words => /8
  3291.        move.w d6,(a6)+
  3292.        move.w #$5C,(a6)+       ;SIZV
  3293.  
  3294.        move.l #$0001005E,(a6)+ ;SIZH+start
  3295.  
  3296. ***
  3297.        movem.l (sp)+,d0-d1/a0-a3
  3298.  
  3299.        move.l a3,a0                  ;scrambled data is now there
  3300.  
  3301. *** init values
  3302.        move.l #$04000096,(a6)+
  3303.        move.l #$80400096,(a6)+
  3304.  
  3305.        move.l #$ffff0044,(a6)+
  3306.        move.l #$ffff0046,(a6)+
  3307.  
  3308. ;offsets to end of buffers for blitter DESCing
  3309.        move.l d0,d6                   ;len of chscr
  3310.        move.l d6,d5 
  3311.      lsr.l #1,d5     ;len of buf2
  3312.        move.l d6,d4 
  3313.      lsr.l #2,d4     ;len of 1 plane = 320*128/8, ok.
  3314.  
  3315. *** Pass 1, planes 7654
  3316.  
  3317.       lea (a0),a3
  3318.        move.l a3,(a6)+ 
  3319.      move.w #$004c,-2(a6) ;B
  3320.       move.w a3,(a6)+ 
  3321.      move.w #$004e,(a6)+
  3322.       lea 2(a0),a3
  3323.        move.l a3,(a6)+ 
  3324.      move.w #$0050,-2(a6) ;A
  3325.        move.w a3,(a6)+ 
  3326.      move.w #$0052,(a6)+
  3327.  
  3328.        move.l a2,(a6)+ 
  3329.     move.w #$0054,-2(a6) ;D
  3330.        move.w a2,(a6)+ 
  3331.     move.w #$0056,(a6)+
  3332.  
  3333.        move.l #$4de40040,(a6)+
  3334.        move.l #$00000042,(a6)+
  3335.        move.l #$0f0f0070,(a6)+ ;cdat
  3336.  
  3337.        move.l #$00020064,(a6)+ 
  3338.     move.l #$00020062,(a6)+ ;a/b mod
  3339.        move.l #$00000066,(a6)+ ;d mod
  3340.  
  3341.        move.w d4,(a6)+         ;d4: nr_pix/4 (words!)
  3342.        move.w #$5C,(a6)+       ;SIZV
  3343.  
  3344.        move.l #$0001005E,(a6)+ ;SIZH+start
  3345.  
  3346. *** Pass 2, planes 76
  3347.  
  3348.       lea (a2),a3
  3349.        move.l a3,(a6)+ 
  3350.      move.w #$004c,-2(a6) ;B
  3351.       move.w a3,(a6)+ 
  3352.      move.w #$004e,(a6)+
  3353.       lea 2(a2),a3
  3354.        move.l a3,(a6)+ 
  3355.      move.w #$0050,-2(a6) ;A
  3356.        move.w a3,(a6)+ 
  3357.      move.w #$0052,(a6)+
  3358.       lea (a1),a3
  3359.       add.w d1,a3 
  3360.     add.w d1,a3 
  3361.      add.w d1,a3   ;4th "doubleplane"
  3362.       move.l a3,(a6)+ 
  3363.      move.w #$0054,-2(a6) ;D
  3364.        move.w a3,(a6)+ 
  3365.      move.w #$0056,(a6)+
  3366.  
  3367.        move.l #$2de40040,(a6)+
  3368.        move.l #$00000042,(a6)+
  3369.        move.l #$33330070,(a6)+ ;cdat
  3370.  
  3371.        move.l #$00020064,(a6)+ 
  3372.      move.l #$00020062,(a6)+ ;a/b mod
  3373.        move.l #$00000066,(a6)+ ;d mod
  3374.  
  3375.        move.w d4,d0 
  3376.      lsr.w #1,d0
  3377.        move.w d0,(a6)+         ;d4: nr_pix/8 (words!)
  3378.        move.w #$5C,(a6)+       ;SIZV
  3379.  
  3380.        move.l #$0001005E,(a6)+ ;SIZH+start
  3381.  
  3382. *** Pass 2, planes 54
  3383.  
  3384.       lea -2(a2,d5.l),a3
  3385.        move.l a3,(a6)+ 
  3386.     move.w #$004c,-2(a6) ;B
  3387.        move.w a3,(a6)+ 
  3388.      move.w #$004e,(a6)+
  3389.       lea -4(a2,d5.l),a3
  3390.        move.l a3,(a6)+ 
  3391.      move.w #$0050,-2(a6) ;A
  3392.        move.w a3,(a6)+ 
  3393.      move.w #$0052,(a6)+
  3394.       lea -2(a1,d4.l),a3
  3395.       add.w d1,a3 
  3396.      add.w d1,a3   ;3rd "doubleplane"
  3397.        move.l a3,(a6)+ 
  3398.      move.w #$0054,-2(a6) ;D
  3399.        move.w a3,(a6)+ 
  3400.      move.w #$0056,(a6)+
  3401.  
  3402.        move.l #$2de40040,(a6)+
  3403.        move.l #$00020042,(a6)+                ;DESC
  3404.       move.l #$cccc0070,(a6)+ ;cdat
  3405.  
  3406.        move.l #$00020064,(a6)+ 
  3407.      move.l #$00020062,(a6)+ ;a/b mod
  3408.        move.l #$00000066,(a6)+ ;d mod
  3409.  
  3410.        move.w d4,d0 
  3411.      lsr.w #1,d0
  3412.        move.w d0,(a6)+         ;d4: nr_pix/8 (words!)
  3413.        move.w #$5C,(a6)+       ;SIZV
  3414.  
  3415.        move.l #$0001005E,(a6)+ ;SIZH+start
  3416.  
  3417. *** Pass 1, planes 3210
  3418.  
  3419.       lea -2(a0,d6.l),a3
  3420.        move.l a3,(a6)+ 
  3421.      move.w #$004c,-2(a6) ;B
  3422.        move.w a3,(a6)+ 
  3423.      move.w #$004e,(a6)+
  3424.       lea -4(a0,d6.l),a3
  3425.        move.l a3,(a6)+ 
  3426.      move.w #$0050,-2(a6) ;A
  3427.        move.w a3,(a6)+ 
  3428.      move.w #$0052,(a6)+
  3429.        lea -2(a2,d5.l),a3
  3430.        move.l a3,(a6)+ 
  3431.      move.w #$0054,-2(a6) ;D
  3432.        move.w a3,(a6)+ 
  3433.      move.w #$0056,(a6)+
  3434.  
  3435.       move.l #$4de40040,(a6)+
  3436.        move.l #$00020042,(a6)+
  3437.        move.l #$f0f00070,(a6)+ ;cdat
  3438.  
  3439.       move.l #$00020064,(a6)+ 
  3440.      move.l #$00020062,(a6)+ ;a/b mod
  3441.        move.l #$00000066,(a6)+ ;d mod
  3442.  
  3443.        move.w d4,(a6)+         ;d4: nr_pix/4 (words!)
  3444.        move.w #$5C,(a6)+       ;SIZV
  3445.  
  3446.        move.l #$0001005E,(a6)+ ;SIZH+start
  3447.  
  3448. *** Pass 2, planes 32
  3449.  
  3450.       lea (a2),a3
  3451.        move.l a3,(a6)+ 
  3452.      move.w #$004c,-2(a6) ;B
  3453.        move.w a3,(a6)+ 
  3454.      move.w #$004e,(a6)+
  3455.       lea 2(a2),a3
  3456.        move.l a3,(a6)+ 
  3457.      move.w #$0050,-2(a6) ;A
  3458.        move.w a3,(a6)+ 
  3459.      move.w #$0052,(a6)+
  3460.       lea (a1),a3
  3461.        add.w d1,a3   ;2nd "doubleplane"
  3462.        move.l a3,(a6)+ 
  3463.      move.w #$0054,-2(a6) ;D
  3464.        move.w a3,(a6)+ 
  3465.      move.w #$0056,(a6)+
  3466.  
  3467.        move.l #$2de40040,(a6)+
  3468.        move.l #$00000042,(a6)+
  3469.        move.l #$33330070,(a6)+ ;cdat
  3470.  
  3471.        move.l #$00020064,(a6)+ 
  3472.      move.l #$00020062,(a6)+ ;a/b mod
  3473.        move.l #$00000066,(a6)+ ;d mod
  3474.  
  3475.       move.w d4,d0 
  3476.      lsr.w #1,d0
  3477.        move.w d0,(a6)+         ;d4: nr_pix/8 (words!)
  3478.        move.w #$5C,(a6)+       ;SIZV
  3479.  
  3480.        move.l #$0001005E,(a6)+ ;SIZH+start
  3481.  
  3482. *** Pass 2, planes 10
  3483.  
  3484.       lea -2(a2,d5.l),a3
  3485.        move.l a3,(a6)+ 
  3486.      move.w #$004c,-2(a6) ;B
  3487.        move.w a3,(a6)+ 
  3488.      move.w #$004e,(a6)+
  3489.       lea -4(a2,d5.l),a3
  3490.        move.l a3,(a6)+ 
  3491.      move.w #$0050,-2(a6) ;A
  3492.       move.w a3,(a6)+ 
  3493.      move.w #$0052,(a6)+
  3494.       lea -2(a1,d4.l),a3
  3495.          ;1st "doubleplane"
  3496.        move.l a3,(a6)+ 
  3497.     move.w #$0054,-2(a6) ;D
  3498.        move.w a3,(a6)+ 
  3499.      move.w #$0056,(a6)+
  3500.  
  3501.        move.l #$2de40040,(a6)+
  3502.        move.l #$00020042,(a6)+                ;DESC
  3503.        move.l #$cccc0070,(a6)+ ;cdat
  3504.  
  3505.        move.l #$00020064,(a6)+ 
  3506.      move.l #$00020062,(a6)+ ;a/b mod
  3507.        move.l #$00000066,(a6)+ ;d mod
  3508.  
  3509.        move.w d4,d0 
  3510.      lsr.w #1,d0
  3511.        move.w d0,(a6)+         ;d4: nr_pix/8 (words!)
  3512.        move.w #$5C,(a6)+       ;SIZV
  3513.  
  3514.        move.l #$0001005E,(a6)+ ;SIZH+start
  3515.  
  3516. *** end of initblit
  3517.        move.l #0,(a6)+
  3518.  
  3519.        move.w #1,bltbsy ;!!!
  3520.        waitblt
  3521.        move.w #$8040,$dff09c ;activate blit intreq
  3522.        rts
  3523.  
  3524.  
  3525. ; =============================================================================
  3526. ;
  3527. ;                            M U S I C   P L A Y E R
  3528. ;
  3529. ; =============================================================================
  3530.  
  3531. ;**************************************************
  3532. ;*    ----- Protracker V2.3A Playroutine -----    *
  3533. ;**************************************************
  3534.  
  3535. DMAWait = 200 ; Set this as low as possible without losing low notes.
  3536.  
  3537. ; CIA Version 1:
  3538. ; Call SetCIAInt to install the interrupt server. Then call mt_init
  3539. ; to initialize the song. Playback starts when the mt_enable flag
  3540. ; is set to a nonzero value. To end the song and turn off all voices,
  3541. ; call mt_end. At last, call ResetCIAInt to remove the interrupt.
  3542.  
  3543. ; This playroutine is not very fast, optimized or well commented,
  3544. ; but all the new commands in PT2.3 should work.
  3545. ; If it's not good enough, you'll have to change it yourself.
  3546. ; We'll try to write a faster routine soon...
  3547.  
  3548. ; Changes from V1.0C playroutine:
  3549. ; - Vibrato depth changed to be compatible with Noisetracker 2.0.
  3550. ;   You'll have to double all vib. depths on old PT modules.
  3551. ; - Funk Repeat changed to Invert Loop.
  3552. ; - Period set back earlier when stopping an effect.
  3553.  
  3554. ;---- CIA Interrupt ----
  3555.  
  3556. AddICRVector    =   -6
  3557. RemICRVector    =  -12
  3558. LVOOpenResource    = -498
  3559. LVOOpenLibrary     = -552
  3560. LVOCloseLibrary    = -414
  3561. LVODelay    = -198
  3562.  
  3563. ciatalo = $400
  3564. ciatahi = $500
  3565. ciatblo = $600
  3566. ciatbhi = $700
  3567. ciacra  = $E00
  3568. ciacrb  = $F00
  3569.  
  3570. SetCIAInt
  3571.     MOVEQ    #2,D6
  3572.     LEA    $BFD000,A5
  3573.     MOVE.B    #'b',CIAAname+3
  3574. SetCIALoop
  3575.     MOVEQ    #0,D0
  3576.     LEA    CIAAname(PC),A1
  3577.     MOVE.L    4.W,A6
  3578.     JSR    LVOOpenResource(A6)
  3579.     MOVE.L    D0,CIAAbase
  3580.     BEQ.W    mt_Return
  3581.  
  3582.     LEA    GfxName(PC),A1
  3583.     MOVEQ    #0,D0
  3584.     JSR    LVOOpenLibrary(A6)
  3585.     TST.L    D0
  3586.     BEQ.W    ResetCIAInt
  3587.     MOVE.L    D0,A1
  3588.     MOVE.W    206(A1),D0    ; DisplayFlags
  3589.     BTST    #2,D0        ; PAL?
  3590.     BEQ.S    WasNTSC
  3591.     MOVE.L    #1773447,D7 ; PAL
  3592.     BRA.S    sciask
  3593. WasNTSC    MOVE.L    #1789773,D7 ; NTSC
  3594. sciask    MOVE.L    D7,TimerValue
  3595.     DIVU    #125,D7 ; Default to normal 50 Hz timer
  3596.     JSR    LVOCloseLibrary(A6)
  3597.  
  3598.     MOVE.L    CIAAbase(PC),A6
  3599.     CMP.W    #2,D6
  3600.     BEQ.S    TryTimerA
  3601. TryTimerB
  3602.     LEA    MusicIntServer(PC),A1
  3603.     MOVEQ    #1,D0    ; Bit 1: Timer B
  3604.     JSR    AddICRVector(A6)
  3605.     MOVE.L    #1,TimerFlag
  3606.     TST.L    D0
  3607.     BNE.S    CIAError
  3608.     MOVE.L    A5,CIAAaddr
  3609.     MOVE.B    D7,ciatblo(A5)
  3610.     LSR.W    #8,D7
  3611.     MOVE.B    D7,ciatbhi(A5)
  3612.     BSET    #0,ciacrb(A5)
  3613.     RTS
  3614.  
  3615. TryTimerA
  3616.     LEA    MusicIntServer(PC),A1
  3617.     MOVEQ    #0,D0    ; Bit 0: Timer A
  3618.     JSR    AddICRVector(A6)
  3619.     CLR.L    TimerFlag
  3620.     TST.L    D0
  3621.     BNE.S    CIAError
  3622.     MOVE.L    A5,CIAAaddr
  3623.     MOVE.B    D7,ciatalo(A5)
  3624.     LSR.W    #8,D7
  3625.     MOVE.B    D7,ciatahi(A5)
  3626.     BSET    #0,ciacra(A5)
  3627.     RTS
  3628.  
  3629. CIAError
  3630.     MOVE.B    #'a',CIAAname+3
  3631.     LEA    $BFE001,A5
  3632.     SUBQ.W    #1,D6
  3633.     BNE.W    SetCIALoop
  3634.     CLR.L    CIAAbase
  3635.     RTS
  3636.  
  3637. ResetCIAInt
  3638.     MOVE.L    CIAAbase(PC),D0
  3639.     BEQ.W    mt_Return
  3640.     CLR.L    CIAAbase
  3641.     MOVE.L    D0,A6
  3642.     MOVE.L    CIAAaddr(PC),A5
  3643.     TST.L    TimerFlag
  3644.     BEQ.S    ResTimerA
  3645.  
  3646.     BCLR    #0,ciacrb(A5)
  3647.     MOVEQ    #1,D0
  3648.     BRA.S    RemInt
  3649.  
  3650. ResTimerA
  3651.     BCLR    #0,ciacra(A5)
  3652.     MOVEQ    #0,D0
  3653. RemInt    LEA    MusicIntServer(PC),A1
  3654.     MOVEQ    #0,d0
  3655.     JSR    RemICRVector(A6)
  3656.     RTS
  3657.  
  3658. ;---- Tempo ----
  3659.  
  3660. SetTempo
  3661.     MOVE.L    CIAAbase(PC),D2
  3662.     BEQ.W    mt_Return
  3663.     CMP.W    #32,D0
  3664.     BHS.S    setemsk
  3665.     MOVEQ    #32,D0
  3666. setemsk    MOVE.W    D0,RealTempo
  3667.     MOVE.L    TimerValue(PC),D2
  3668.     DIVU    D0,D2
  3669.     MOVE.L    CIAAaddr(PC),A4
  3670.     MOVE.L    TimerFlag(PC),D0
  3671.     BEQ.S    SetTemA
  3672.     MOVE.B    D2,ciatblo(A4)
  3673.     LSR.W    #8,D2
  3674.     MOVE.B    D2,ciatbhi(A4)
  3675.     RTS
  3676.  
  3677. SetTemA    MOVE.B    D2,ciatalo(A4)
  3678.     LSR.W    #8,D2
  3679.     MOVE.B    D2,ciatahi(A4)
  3680.     RTS
  3681.  
  3682. RealTempo    dc.w 125
  3683. CIAAaddr    dc.l 0
  3684. CIAAname    dc.b "ciaa.resource",0
  3685. CIAAbase    dc.l 0
  3686. TimerFlag    dc.l 0
  3687. TimerValue    dc.l 0
  3688. GfxName        dc.b "graphics.library",0,0
  3689.  
  3690. MusicIntServer
  3691.     dc.l 0,0
  3692.     dc.b 2,5 ; type, priority
  3693.     dc.l musintname
  3694.     dc.l 0,mt_music
  3695.  
  3696. musintname    dc.b "Protracker MusicInt",0
  3697.  
  3698. ;---- Playroutine ----
  3699.  
  3700. n_note        EQU    0  ; W
  3701. n_cmd        EQU    2  ; W
  3702. n_cmdlo        EQU    3  ; B
  3703. n_start        EQU    4  ; L
  3704. n_length    EQU    8  ; W
  3705. n_loopstart    EQU    10 ; L
  3706. n_replen    EQU    14 ; W
  3707. n_period    EQU    16 ; W
  3708. n_finetune    EQU    18 ; B
  3709. n_volume    EQU    19 ; B
  3710. n_dmabit    EQU    20 ; W
  3711. n_toneportdirec    EQU    22 ; B
  3712. n_toneportspeed    EQU    23 ; B
  3713. n_wantedperiod    EQU    24 ; W
  3714. n_vibratocmd    EQU    26 ; B
  3715. n_vibratopos    EQU    27 ; B
  3716. n_tremolocmd    EQU    28 ; B
  3717. n_tremolopos    EQU    29 ; B
  3718. n_wavecontrol    EQU    30 ; B
  3719. n_glissfunk    EQU    31 ; B
  3720. n_sampleoffset    EQU    32 ; B
  3721. n_pattpos    EQU    33 ; B
  3722. n_loopcount    EQU    34 ; B
  3723. n_funkoffset    EQU    35 ; B
  3724. n_wavestart    EQU    36 ; L
  3725. n_reallength    EQU    40 ; W
  3726.  
  3727.     ALIGNLONG
  3728. mt_data    dc.l    0
  3729.  
  3730. mt_init    
  3731.     move.l    mt_data,a0        ; Altered by me...allows for multiple
  3732.     MOVE.L    A0,mt_SongDataPtr    ; modules in one source.
  3733.     MOVE.L    A0,A1
  3734.     LEA    952(A1),A1
  3735.     MOVEQ    #127,D0
  3736.     MOVEQ    #0,D1
  3737. mtloop    MOVE.L    D1,D2
  3738.     SUBQ.W    #1,D0
  3739. mtloop2    MOVE.B    (A1)+,D1
  3740.     CMP.B    D2,D1
  3741.     BGT.S    mtloop
  3742.     DBRA    D0,mtloop2
  3743.     ADDQ.B    #1,D2
  3744.             
  3745.     LEA    mt_SampleStarts(PC),A1
  3746.     ASL.L    #8,D2
  3747.     ASL.L    #2,D2
  3748.     ADD.L    #1084,D2
  3749.     ADD.L    A0,D2
  3750.     MOVE.L    D2,A2
  3751.     MOVEQ    #30,D0
  3752. mtloop3    CLR.L    (A2)
  3753.     MOVE.L    A2,(A1)+
  3754.     MOVEQ    #0,D1
  3755.     MOVE.W    42(A0),D1
  3756.     ASL.L    #1,D1
  3757.     ADD.L    D1,A2
  3758.     ADD.L    #30,A0
  3759.     DBRA    D0,mtloop3
  3760.  
  3761.     OR.B    #2,$BFE001
  3762.     MOVE.B    #6,mt_speed
  3763.     CLR.B    mt_counter
  3764.     CLR.B    mt_SongPos
  3765.     CLR.W    mt_PatternPos
  3766. mt_end    SF    mt_Enable
  3767.     LEA    $DFF000,A0
  3768.     CLR.W    $A8(A0)
  3769.     CLR.W    $B8(A0)
  3770.     CLR.W    $C8(A0)
  3771.     CLR.W    $D8(A0)
  3772.     MOVE.W    #$F,$DFF096
  3773.     RTS
  3774.  
  3775.     ALIGNLONG
  3776.     
  3777. mt_music
  3778.     MOVEM.L    D0-D4/A0-A6,-(SP)
  3779.     TST.B    mt_Enable
  3780.     BEQ.W    mt_exit
  3781.     ADDQ.B    #1,mt_counter
  3782.     MOVE.B    mt_counter(PC),D0
  3783.     CMP.B    mt_speed(PC),D0
  3784.     BLO.S    mt_NoNewNote
  3785.     CLR.B    mt_counter
  3786.     TST.B    mt_PattDelTime2
  3787.     BEQ.S    mt_GetNewNote
  3788.     BSR.S    mt_NoNewAllChannels
  3789.     BRA.W    mt_dskip
  3790.  
  3791. mt_NoNewNote
  3792.     BSR.S    mt_NoNewAllChannels
  3793.     BRA.W    mt_NoNewPosYet
  3794.  
  3795. mt_NoNewAllChannels
  3796.     LEA    $DFF0A0,A5
  3797.     LEA    mt_chan1temp(PC),A6
  3798.     BSR.W    mt_CheckEfx
  3799.     LEA    $DFF0B0,A5
  3800.     LEA    mt_chan2temp(PC),A6
  3801.     BSR.W    mt_CheckEfx
  3802.     LEA    $DFF0C0,A5
  3803.     LEA    mt_chan3temp(PC),A6
  3804.     BSR.W    mt_CheckEfx
  3805.     LEA    $DFF0D0,A5
  3806.     LEA    mt_chan4temp(PC),A6
  3807.     BRA.W    mt_CheckEfx
  3808.  
  3809. mt_GetNewNote
  3810.     MOVE.L    mt_SongDataPtr(PC),A0
  3811.     LEA    12(A0),A3
  3812.     LEA    952(A0),A2    ;pattpo
  3813.     LEA    1084(A0),A0    ;patterndata
  3814.     MOVEQ    #0,D0
  3815.     MOVEQ    #0,D1
  3816.     MOVE.B    mt_SongPos(PC),D0
  3817.     MOVE.B    (A2,D0.W),D1
  3818.     ASL.L    #8,D1
  3819.     ASL.L    #2,D1
  3820.     ADD.W    mt_PatternPos(PC),D1
  3821.     CLR.W    mt_DMACONtemp
  3822.  
  3823.     LEA    $DFF0A0,A5
  3824.     LEA    mt_chan1temp(PC),A6
  3825.     BSR.S    mt_PlayVoice
  3826.     LEA    $DFF0B0,A5
  3827.     LEA    mt_chan2temp(PC),A6
  3828.     BSR.S    mt_PlayVoice
  3829.     LEA    $DFF0C0,A5
  3830.     LEA    mt_chan3temp(PC),A6
  3831.     BSR.S    mt_PlayVoice
  3832.     LEA    $DFF0D0,A5
  3833.     LEA    mt_chan4temp(PC),A6
  3834.     BSR.S    mt_PlayVoice
  3835.     BRA.W    mt_SetDMA
  3836.  
  3837. mt_PlayVoice
  3838.     TST.L    (A6)
  3839.     BNE.S    mt_plvskip
  3840.     BSR.W    mt_PerNop
  3841. mt_plvskip
  3842.     MOVE.L    (A0,D1.L),(A6)
  3843.     ADDQ.L    #4,D1
  3844.     MOVEQ    #0,D2
  3845.     MOVE.B    n_cmd(A6),D2
  3846.     AND.B    #$F0,D2
  3847.     LSR.B    #4,D2
  3848.     MOVE.B    (A6),D0
  3849.     AND.B    #$F0,D0
  3850.     OR.B    D0,D2
  3851.     TST.B    D2
  3852.     BEQ.W    mt_SetRegs
  3853.     MOVEQ    #0,D3
  3854.     LEA    mt_SampleStarts(PC),A1
  3855.     MOVE    D2,D4
  3856.     SUBQ.L    #1,D2
  3857.     ASL.L    #2,D2
  3858.     MULU    #30,D4
  3859.     MOVE.L    (A1,D2.L),n_start(A6)
  3860.     MOVE.W    (A3,D4.L),n_length(A6)
  3861.     MOVE.W    (A3,D4.L),n_reallength(A6)
  3862.     MOVE.B    2(A3,D4.L),n_finetune(A6)
  3863.     MOVE.B    3(A3,D4.L),n_volume(A6)
  3864.     MOVE.W    4(A3,D4.L),D3 ; Get repeat
  3865.     TST.W    D3
  3866.     BEQ.S    mt_NoLoop
  3867.     MOVE.L    n_start(A6),D2    ; Get start
  3868.     ASL.W    #1,D3
  3869.     ADD.L    D3,D2        ; Add repeat
  3870.     MOVE.L    D2,n_loopstart(A6)
  3871.     MOVE.L    D2,n_wavestart(A6)
  3872.     MOVE.W    4(A3,D4.L),D0    ; Get repeat
  3873.     ADD.W    6(A3,D4.L),D0    ; Add replen
  3874.     MOVE.W    D0,n_length(A6)
  3875.     MOVE.W    6(A3,D4.L),n_replen(A6)    ; Save replen
  3876.     MOVEQ    #0,D0
  3877.     MOVE.B    n_volume(A6),D0
  3878.     MOVE.W    D0,8(A5)    ; Set volume
  3879.     BRA.S    mt_SetRegs
  3880.  
  3881. mt_NoLoop
  3882.     MOVE.L    n_start(A6),D2
  3883.     ADD.L    D3,D2
  3884.     MOVE.L    D2,n_loopstart(A6)
  3885.     MOVE.L    D2,n_wavestart(A6)
  3886.     MOVE.W    6(A3,D4.L),n_replen(A6)    ; Save replen
  3887.     MOVEQ    #0,D0
  3888.     MOVE.B    n_volume(A6),D0
  3889.     MOVE.W    D0,8(A5)    ; Set volume
  3890. mt_SetRegs
  3891.     MOVE.W    (A6),D0
  3892.     AND.W    #$0FFF,D0
  3893.     BEQ.W    mt_CheckMoreEfx    ; If no note
  3894.     MOVE.W    2(A6),D0
  3895.     AND.W    #$0FF0,D0
  3896.     CMP.W    #$0E50,D0
  3897.     BEQ.S    mt_DoSetFineTune
  3898.     MOVE.B    2(A6),D0
  3899.     AND.B    #$0F,D0
  3900.     CMP.B    #3,D0    ; TonePortamento
  3901.     BEQ.S    mt_ChkTonePorta
  3902.     CMP.B    #5,D0
  3903.     BEQ.S    mt_ChkTonePorta
  3904.     CMP.B    #9,D0    ; Sample Offset
  3905.     BNE.S    mt_SetPeriod
  3906.     BSR.W    mt_CheckMoreEfx
  3907.     BRA.S    mt_SetPeriod
  3908.  
  3909. mt_DoSetFineTune
  3910.     BSR.W    mt_SetFineTune
  3911.     BRA.S    mt_SetPeriod
  3912.  
  3913. mt_ChkTonePorta
  3914.     BSR.W    mt_SetTonePorta
  3915.     BRA.W    mt_CheckMoreEfx
  3916.  
  3917. mt_SetPeriod
  3918.     MOVEM.L    D0-D1/A0-A1,-(SP)
  3919.     MOVE.W    (A6),D1
  3920.     AND.W    #$0FFF,D1
  3921.     LEA    mt_PeriodTable(PC),A1
  3922.     MOVEQ    #0,D0
  3923.     MOVEQ    #36,D2
  3924. mt_ftuloop
  3925.     CMP.W    (A1,D0.W),D1
  3926.     BHS.S    mt_ftufound
  3927.     ADDQ.L    #2,D0
  3928.     DBRA    D2,mt_ftuloop
  3929. mt_ftufound
  3930.     MOVEQ    #0,D1
  3931.     MOVE.B    n_finetune(A6),D1
  3932.     MULU    #36*2,D1
  3933.     ADD.L    D1,A1
  3934.     MOVE.W    (A1,D0.W),n_period(A6)
  3935.     MOVEM.L    (SP)+,D0-D1/A0-A1
  3936.  
  3937.     MOVE.W    2(A6),D0
  3938.     AND.W    #$0FF0,D0
  3939.     CMP.W    #$0ED0,D0 ; Notedelay
  3940.     BEQ.W    mt_CheckMoreEfx
  3941.  
  3942.     MOVE.W    n_dmabit(A6),$DFF096
  3943.     BTST    #2,n_wavecontrol(A6)
  3944.     BNE.S    mt_vibnoc
  3945.     CLR.B    n_vibratopos(A6)
  3946. mt_vibnoc
  3947.     BTST    #6,n_wavecontrol(A6)
  3948.     BNE.S    mt_trenoc
  3949.     CLR.B    n_tremolopos(A6)
  3950. mt_trenoc
  3951.     MOVE.L    n_start(A6),(A5)    ; Set start
  3952.     MOVE.W    n_length(A6),4(A5)    ; Set length
  3953.     MOVE.W    n_period(A6),D0
  3954.     MOVE.W    D0,6(A5)        ; Set period
  3955.     MOVE.W    n_dmabit(A6),D0
  3956.     OR.W    D0,mt_DMACONtemp
  3957.     BRA.W    mt_CheckMoreEfx
  3958.  
  3959. mt_SetDMA
  3960.     MOVE.W    #300,D0
  3961. mt_WaitDMA
  3962.     DBRA    D0,mt_WaitDMA
  3963.     MOVE.W    mt_DMACONtemp(PC),D0
  3964.     OR.W    #$8000,D0
  3965.     MOVE.W    D0,$DFF096
  3966.     MOVE.W    #300,D0
  3967. mt_WaitDMA2
  3968.     DBRA    D0,mt_WaitDMA2
  3969.  
  3970.     LEA    $DFF000,A5
  3971.     LEA    mt_chan4temp(PC),A6
  3972.     MOVE.L    n_loopstart(A6),$D0(A5)
  3973.     MOVE.W    n_replen(A6),$D4(A5)
  3974.     LEA    mt_chan3temp(PC),A6
  3975.     MOVE.L    n_loopstart(A6),$C0(A5)
  3976.     MOVE.W    n_replen(A6),$C4(A5)
  3977.     LEA    mt_chan2temp(PC),A6
  3978.     MOVE.L    n_loopstart(A6),$B0(A5)
  3979.     MOVE.W    n_replen(A6),$B4(A5)
  3980.     LEA    mt_chan1temp(PC),A6
  3981.     MOVE.L    n_loopstart(A6),$A0(A5)
  3982.     MOVE.W    n_replen(A6),$A4(A5)
  3983.  
  3984. mt_dskip
  3985.     ADD.W    #16,mt_PatternPos
  3986.     MOVE.B    mt_PattDelTime,D0
  3987.     BEQ.S    mt_dskc
  3988.     MOVE.B    D0,mt_PattDelTime2
  3989.     CLR.B    mt_PattDelTime
  3990. mt_dskc    TST.B    mt_PattDelTime2
  3991.     BEQ.S    mt_dska
  3992.     SUBQ.B    #1,mt_PattDelTime2
  3993.     BEQ.S    mt_dska
  3994.     SUB.W    #16,mt_PatternPos
  3995. mt_dska    TST.B    mt_PBreakFlag
  3996.     BEQ.S    mt_nnpysk
  3997.     SF    mt_PBreakFlag
  3998.     MOVEQ    #0,D0
  3999.     MOVE.B    mt_PBreakPos(PC),D0
  4000.     CLR.B    mt_PBreakPos
  4001.     LSL.W    #4,D0
  4002.     MOVE.W    D0,mt_PatternPos
  4003. mt_nnpysk
  4004.     CMP.W    #1024,mt_PatternPos
  4005.     BLO.S    mt_NoNewPosYet
  4006. mt_NextPosition    
  4007.     MOVEQ    #0,D0
  4008.     MOVE.B    mt_PBreakPos(PC),D0
  4009.     LSL.W    #4,D0
  4010.     MOVE.W    D0,mt_PatternPos
  4011.     CLR.B    mt_PBreakPos
  4012.     CLR.B    mt_PosJumpFlag
  4013.     ADDQ.B    #1,mt_SongPos
  4014.     AND.B    #$7F,mt_SongPos
  4015.     MOVE.B    mt_SongPos(PC),D1
  4016.     MOVE.L    mt_SongDataPtr(PC),A0
  4017.     CMP.B    950(A0),D1
  4018.     BLO.S    mt_NoNewPosYet
  4019.     CLR.B    mt_SongPos
  4020. mt_NoNewPosYet    
  4021.     TST.B    mt_PosJumpFlag
  4022.     BNE.S    mt_NextPosition
  4023. mt_exit    MOVEM.L    (SP)+,D0-D4/A0-A6
  4024.     RTS
  4025.  
  4026. mt_CheckEfx
  4027.     BSR.W    mt_UpdateFunk
  4028.     MOVE.W    n_cmd(A6),D0
  4029.     AND.W    #$0FFF,D0
  4030.     BEQ.S    mt_PerNop
  4031.     MOVE.B    n_cmd(A6),D0
  4032.     AND.B    #$0F,D0
  4033.     BEQ.S    mt_Arpeggio
  4034.     CMP.B    #1,D0
  4035.     BEQ.W    mt_PortaUp
  4036.     CMP.B    #2,D0
  4037.     BEQ.W    mt_PortaDown
  4038.     CMP.B    #3,D0
  4039.     BEQ.W    mt_TonePortamento
  4040.     CMP.B    #4,D0
  4041.     BEQ.W    mt_Vibrato
  4042.     CMP.B    #5,D0
  4043.     BEQ.W    mt_TonePlusVolSlide
  4044.     CMP.B    #6,D0
  4045.     BEQ.W    mt_VibratoPlusVolSlide
  4046.     CMP.B    #$E,D0
  4047.     BEQ.W    mt_E_Commands
  4048. SetBack    MOVE.W    n_period(A6),6(A5)
  4049.     CMP.B    #7,D0
  4050.     BEQ.W    mt_Tremolo
  4051.     CMP.B    #$A,D0
  4052.     BEQ.W    mt_VolumeSlide
  4053. mt_Return
  4054.     RTS
  4055.  
  4056. mt_PerNop
  4057.     MOVE.W    n_period(A6),6(A5)
  4058.     RTS
  4059.  
  4060. mt_Arpeggio
  4061.     MOVEQ    #0,D0
  4062.     MOVE.B    mt_counter(PC),D0
  4063.     DIVS    #3,D0
  4064.     SWAP    D0
  4065.     CMP.W    #0,D0
  4066.     BEQ.S    mt_Arpeggio2
  4067.     CMP.W    #2,D0
  4068.     BEQ.S    mt_Arpeggio1
  4069.     MOVEQ    #0,D0
  4070.     MOVE.B    n_cmdlo(A6),D0
  4071.     LSR.B    #4,D0
  4072.     BRA.S    mt_Arpeggio3
  4073.  
  4074. mt_Arpeggio1
  4075.     MOVEQ    #0,D0
  4076.     MOVE.B    n_cmdlo(A6),D0
  4077.     AND.B    #15,D0
  4078.     BRA.S    mt_Arpeggio3
  4079.  
  4080. mt_Arpeggio2
  4081.     MOVE.W    n_period(A6),D2
  4082.     BRA.S    mt_Arpeggio4
  4083.  
  4084. mt_Arpeggio3
  4085.     ASL.W    #1,D0
  4086.     MOVEQ    #0,D1
  4087.     MOVE.B    n_finetune(A6),D1
  4088.     MULU    #36*2,D1
  4089.     LEA    mt_PeriodTable(PC),A0
  4090.     ADD.L    D1,A0
  4091.     MOVEQ    #0,D1
  4092.     MOVE.W    n_period(A6),D1
  4093.     MOVEQ    #36,D3
  4094. mt_arploop
  4095.     MOVE.W    (A0,D0.W),D2
  4096.     CMP.W    (A0),D1
  4097.     BHS.S    mt_Arpeggio4
  4098.     ADDQ.L    #2,A0
  4099.     DBRA    D3,mt_arploop
  4100.     RTS
  4101.  
  4102. mt_Arpeggio4
  4103.     MOVE.W    D2,6(A5)
  4104.     RTS
  4105.  
  4106. mt_FinePortaUp
  4107.     TST.B    mt_counter
  4108.     BNE.S    mt_Return
  4109.     MOVE.B    #$0F,mt_LowMask
  4110. mt_PortaUp
  4111.     MOVEQ    #0,D0
  4112.     MOVE.B    n_cmdlo(A6),D0
  4113.     AND.B    mt_LowMask(PC),D0
  4114.     MOVE.B    #$FF,mt_LowMask
  4115.     SUB.W    D0,n_period(A6)
  4116.     MOVE.W    n_period(A6),D0
  4117.     AND.W    #$0FFF,D0
  4118.     CMP.W    #113,D0
  4119.     BPL.S    mt_PortaUskip
  4120.     AND.W    #$F000,n_period(A6)
  4121.     OR.W    #113,n_period(A6)
  4122. mt_PortaUskip
  4123.     MOVE.W    n_period(A6),D0
  4124.     AND.W    #$0FFF,D0
  4125.     MOVE.W    D0,6(A5)
  4126.     RTS    
  4127.  
  4128. mt_FinePortaDown
  4129.     TST.B    mt_counter
  4130.     BNE.W    mt_Return
  4131.     MOVE.B    #$0F,mt_LowMask
  4132. mt_PortaDown
  4133.     CLR.W    D0
  4134.     MOVE.B    n_cmdlo(A6),D0
  4135.     AND.B    mt_LowMask(PC),D0
  4136.     MOVE.B    #$FF,mt_LowMask
  4137.     ADD.W    D0,n_period(A6)
  4138.     MOVE.W    n_period(A6),D0
  4139.     AND.W    #$0FFF,D0
  4140.     CMP.W    #856,D0
  4141.     BMI.S    mt_PortaDskip
  4142.     AND.W    #$F000,n_period(A6)
  4143.     OR.W    #856,n_period(A6)
  4144. mt_PortaDskip
  4145.     MOVE.W    n_period(A6),D0
  4146.     AND.W    #$0FFF,D0
  4147.     MOVE.W    D0,6(A5)
  4148.     RTS
  4149.  
  4150. mt_SetTonePorta
  4151.     MOVE.L    A0,-(SP)
  4152.     MOVE.W    (A6),D2
  4153.     AND.W    #$0FFF,D2
  4154.     MOVEQ    #0,D0
  4155.     MOVE.B    n_finetune(A6),D0
  4156.     MULU    #36*2,D0 ;37?
  4157.     LEA    mt_PeriodTable(PC),A0
  4158.     ADD.L    D0,A0
  4159.     MOVEQ    #0,D0
  4160. mt_StpLoop
  4161.     CMP.W    (A0,D0.W),D2
  4162.     BHS.S    mt_StpFound
  4163.     ADDQ.W    #2,D0
  4164.     CMP.W    #36*2,D0 ;37?
  4165.     BLO.S    mt_StpLoop
  4166.     MOVEQ    #35*2,D0
  4167. mt_StpFound
  4168.     MOVE.B    n_finetune(A6),D2
  4169.     AND.B    #8,D2
  4170.     BEQ.S    mt_StpGoss
  4171.     TST.W    D0
  4172.     BEQ.S    mt_StpGoss
  4173.     SUBQ.W    #2,D0
  4174. mt_StpGoss
  4175.     MOVE.W    (A0,D0.W),D2
  4176.     MOVE.L    (SP)+,A0
  4177.     MOVE.W    D2,n_wantedperiod(A6)
  4178.     MOVE.W    n_period(A6),D0
  4179.     CLR.B    n_toneportdirec(A6)
  4180.     CMP.W    D0,D2
  4181.     BEQ.S    mt_ClearTonePorta
  4182.     BGE.W    mt_Return
  4183.     MOVE.B    #1,n_toneportdirec(A6)
  4184.     RTS
  4185.  
  4186. mt_ClearTonePorta
  4187.     CLR.W    n_wantedperiod(A6)
  4188.     RTS
  4189.  
  4190. mt_TonePortamento
  4191.     MOVE.B    n_cmdlo(A6),D0
  4192.     BEQ.S    mt_TonePortNoChange
  4193.     MOVE.B    D0,n_toneportspeed(A6)
  4194.     CLR.B    n_cmdlo(A6)
  4195. mt_TonePortNoChange
  4196.     TST.W    n_wantedperiod(A6)
  4197.     BEQ.W    mt_Return
  4198.     MOVEQ    #0,D0
  4199.     MOVE.B    n_toneportspeed(A6),D0
  4200.     TST.B    n_toneportdirec(A6)
  4201.     BNE.S    mt_TonePortaUp
  4202. mt_TonePortaDown
  4203.     ADD.W    D0,n_period(A6)
  4204.     MOVE.W    n_wantedperiod(A6),D0
  4205.     CMP.W    n_period(A6),D0
  4206.     BGT.S    mt_TonePortaSetPer
  4207.     MOVE.W    n_wantedperiod(A6),n_period(A6)
  4208.     CLR.W    n_wantedperiod(A6)
  4209.     BRA.S    mt_TonePortaSetPer
  4210.  
  4211. mt_TonePortaUp
  4212.     SUB.W    D0,n_period(A6)
  4213.     MOVE.W    n_wantedperiod(A6),D0
  4214.     CMP.W    n_period(A6),D0
  4215.     BLT.S    mt_TonePortaSetPer
  4216.     MOVE.W    n_wantedperiod(A6),n_period(A6)
  4217.     CLR.W    n_wantedperiod(A6)
  4218.  
  4219. mt_TonePortaSetPer
  4220.     MOVE.W    n_period(A6),D2
  4221.     MOVE.B    n_glissfunk(A6),D0
  4222.     AND.B    #$0F,D0
  4223.     BEQ.S    mt_GlissSkip
  4224.     MOVEQ    #0,D0
  4225.     MOVE.B    n_finetune(A6),D0
  4226.     MULU    #36*2,D0
  4227.     LEA    mt_PeriodTable(PC),A0
  4228.     ADD.L    D0,A0
  4229.     MOVEQ    #0,D0
  4230. mt_GlissLoop
  4231.     CMP.W    (A0,D0.W),D2
  4232.     BHS.S    mt_GlissFound
  4233.     ADDQ.W    #2,D0
  4234.     CMP.W    #36*2,D0
  4235.     BLO.S    mt_GlissLoop
  4236.     MOVEQ    #35*2,D0
  4237. mt_GlissFound
  4238.     MOVE.W    (A0,D0.W),D2
  4239. mt_GlissSkip
  4240.     MOVE.W    D2,6(A5) ; Set period
  4241.     RTS
  4242.  
  4243. mt_Vibrato
  4244.     MOVE.B    n_cmdlo(A6),D0
  4245.     BEQ.S    mt_Vibrato2
  4246.     MOVE.B    n_vibratocmd(A6),D2
  4247.     AND.B    #$0F,D0
  4248.     BEQ.S    mt_vibskip
  4249.     AND.B    #$F0,D2
  4250.     OR.B    D0,D2
  4251. mt_vibskip
  4252.     MOVE.B    n_cmdlo(A6),D0
  4253.     AND.B    #$F0,D0
  4254.     BEQ.S    mt_vibskip2
  4255.     AND.B    #$0F,D2
  4256.     OR.B    D0,D2
  4257. mt_vibskip2
  4258.     MOVE.B    D2,n_vibratocmd(A6)
  4259. mt_Vibrato2
  4260.     MOVE.B    n_vibratopos(A6),D0
  4261.     LEA    mt_VibratoTable(PC),A4
  4262.     LSR.W    #2,D0
  4263.     AND.W    #$001F,D0
  4264.     MOVEQ    #0,D2
  4265.     MOVE.B    n_wavecontrol(A6),D2
  4266.     AND.B    #$03,D2
  4267.     BEQ.S    mt_vib_sine
  4268.     LSL.B    #3,D0
  4269.     CMP.B    #1,D2
  4270.     BEQ.S    mt_vib_rampdown
  4271.     MOVE.B    #255,D2
  4272.     BRA.S    mt_vib_set
  4273. mt_vib_rampdown
  4274.     TST.B    n_vibratopos(A6)
  4275.     BPL.S    mt_vib_rampdown2
  4276.     MOVE.B    #255,D2
  4277.     SUB.B    D0,D2
  4278.     BRA.S    mt_vib_set
  4279. mt_vib_rampdown2
  4280.     MOVE.B    D0,D2
  4281.     BRA.S    mt_vib_set
  4282. mt_vib_sine
  4283.     MOVE.B    (A4,D0.W),D2
  4284. mt_vib_set
  4285.     MOVE.B    n_vibratocmd(A6),D0
  4286.     AND.W    #15,D0
  4287.     MULU    D0,D2
  4288.     LSR.W    #7,D2
  4289.     MOVE.W    n_period(A6),D0
  4290.     TST.B    n_vibratopos(A6)
  4291.     BMI.S    mt_VibratoNeg
  4292.     ADD.W    D2,D0
  4293.     BRA.S    mt_Vibrato3
  4294. mt_VibratoNeg
  4295.     SUB.W    D2,D0
  4296. mt_Vibrato3
  4297.     MOVE.W    D0,6(A5)
  4298.     MOVE.B    n_vibratocmd(A6),D0
  4299.     LSR.W    #2,D0
  4300.     AND.W    #$003C,D0
  4301.     ADD.B    D0,n_vibratopos(A6)
  4302.     RTS
  4303.  
  4304. mt_TonePlusVolSlide
  4305.     BSR.W    mt_TonePortNoChange
  4306.     BRA.W    mt_VolumeSlide
  4307.  
  4308. mt_VibratoPlusVolSlide
  4309.     BSR.S    mt_Vibrato2
  4310.     BRA.W    mt_VolumeSlide
  4311.  
  4312. mt_Tremolo
  4313.     MOVE.B    n_cmdlo(A6),D0
  4314.     BEQ.S    mt_Tremolo2
  4315.     MOVE.B    n_tremolocmd(A6),D2
  4316.     AND.B    #$0F,D0
  4317.     BEQ.S    mt_treskip
  4318.     AND.B    #$F0,D2
  4319.     OR.B    D0,D2
  4320. mt_treskip
  4321.     MOVE.B    n_cmdlo(A6),D0
  4322.     AND.B    #$F0,D0
  4323.     BEQ.S    mt_treskip2
  4324.     AND.B    #$0F,D2
  4325.     OR.B    D0,D2
  4326. mt_treskip2
  4327.     MOVE.B    D2,n_tremolocmd(A6)
  4328. mt_Tremolo2
  4329.     MOVE.B    n_tremolopos(A6),D0
  4330.     LEA    mt_VibratoTable(PC),A4
  4331.     LSR.W    #2,D0
  4332.     AND.W    #$001F,D0
  4333.     MOVEQ    #0,D2
  4334.     MOVE.B    n_wavecontrol(A6),D2
  4335.     LSR.B    #4,D2
  4336.     AND.B    #$03,D2
  4337.     BEQ.S    mt_tre_sine
  4338.     LSL.B    #3,D0
  4339.     CMP.B    #1,D2
  4340.     BEQ.S    mt_tre_rampdown
  4341.     MOVE.B    #255,D2
  4342.     BRA.S    mt_tre_set
  4343. mt_tre_rampdown
  4344.     TST.B    n_vibratopos(A6)
  4345.     BPL.S    mt_tre_rampdown2
  4346.     MOVE.B    #255,D2
  4347.     SUB.B    D0,D2
  4348.     BRA.S    mt_tre_set
  4349. mt_tre_rampdown2
  4350.     MOVE.B    D0,D2
  4351.     BRA.S    mt_tre_set
  4352. mt_tre_sine
  4353.     MOVE.B    (A4,D0.W),D2
  4354. mt_tre_set
  4355.     MOVE.B    n_tremolocmd(A6),D0
  4356.     AND.W    #15,D0
  4357.     MULU    D0,D2
  4358.     LSR.W    #6,D2
  4359.     MOVEQ    #0,D0
  4360.     MOVE.B    n_volume(A6),D0
  4361.     TST.B    n_tremolopos(A6)
  4362.     BMI.S    mt_TremoloNeg
  4363.     ADD.W    D2,D0
  4364.     BRA.S    mt_Tremolo3
  4365. mt_TremoloNeg
  4366.     SUB.W    D2,D0
  4367. mt_Tremolo3
  4368.     BPL.S    mt_TremoloSkip
  4369.     CLR.W    D0
  4370. mt_TremoloSkip
  4371.     CMP.W    #$40,D0
  4372.     BLS.S    mt_TremoloOk
  4373.     MOVE.W    #$40,D0
  4374. mt_TremoloOk
  4375.     MOVE.W    D0,8(A5)
  4376.     MOVE.B    n_tremolocmd(A6),D0
  4377.     LSR.W    #2,D0
  4378.     AND.W    #$003C,D0
  4379.     ADD.B    D0,n_tremolopos(A6)
  4380.     RTS
  4381.  
  4382. mt_SampleOffset
  4383.     MOVEQ    #0,D0
  4384.     MOVE.B    n_cmdlo(A6),D0
  4385.     BEQ.S    mt_sononew
  4386.     MOVE.B    D0,n_sampleoffset(A6)
  4387. mt_sononew
  4388.     MOVE.B    n_sampleoffset(A6),D0
  4389.     LSL.W    #7,D0
  4390.     CMP.W    n_length(A6),D0
  4391.     BGE.S    mt_sofskip
  4392.     SUB.W    D0,n_length(A6)
  4393.     LSL.W    #1,D0
  4394.     ADD.L    D0,n_start(A6)
  4395.     RTS
  4396. mt_sofskip
  4397.     MOVE.W    #$0001,n_length(A6)
  4398.     RTS
  4399.  
  4400. mt_VolumeSlide
  4401.     MOVEQ    #0,D0
  4402.     MOVE.B    n_cmdlo(A6),D0
  4403.     LSR.B    #4,D0
  4404.     TST.B    D0
  4405.     BEQ.S    mt_VolSlideDown
  4406. mt_VolSlideUp
  4407.     ADD.B    D0,n_volume(A6)
  4408.     CMP.B    #$40,n_volume(A6)
  4409.     BMI.S    mt_vsuskip
  4410.     MOVE.B    #$40,n_volume(A6)
  4411. mt_vsuskip
  4412.     MOVE.B    n_volume(A6),D0
  4413.     MOVE.W    D0,8(A5)
  4414.     RTS
  4415.  
  4416. mt_VolSlideDown
  4417.     MOVEQ    #0,D0
  4418.     MOVE.B    n_cmdlo(A6),D0
  4419.     AND.B    #$0F,D0
  4420. mt_VolSlideDown2
  4421.     SUB.B    D0,n_volume(A6)
  4422.     BPL.S    mt_vsdskip
  4423.     CLR.B    n_volume(A6)
  4424. mt_vsdskip
  4425.     MOVE.B    n_volume(A6),D0
  4426.     MOVE.W    D0,8(A5)
  4427.     RTS
  4428.  
  4429. mt_PositionJump
  4430.     MOVE.B    n_cmdlo(A6),D0
  4431.     SUBQ.B    #1,D0
  4432.     MOVE.B    D0,mt_SongPos
  4433. mt_pj2    CLR.B    mt_PBreakPos
  4434.     ST     mt_PosJumpFlag
  4435.     RTS
  4436.  
  4437. mt_VolumeChange
  4438.     MOVEQ    #0,D0
  4439.     MOVE.B    n_cmdlo(A6),D0
  4440.     CMP.B    #$40,D0
  4441.     BLS.S    mt_VolumeOk
  4442.     MOVEQ    #$40,D0
  4443. mt_VolumeOk
  4444.     MOVE.B    D0,n_volume(A6)
  4445.     MOVE.W    D0,8(A5)
  4446.     RTS
  4447.  
  4448. mt_PatternBreak
  4449.     MOVEQ    #0,D0
  4450.     MOVE.B    n_cmdlo(A6),D0
  4451.     MOVE.L    D0,D2
  4452.     LSR.B    #4,D0
  4453.     MULU    #10,D0
  4454.     AND.B    #$0F,D2
  4455.     ADD.B    D2,D0
  4456.     CMP.B    #63,D0
  4457.     BHI.S    mt_pj2
  4458.     MOVE.B    D0,mt_PBreakPos
  4459.     ST    mt_PosJumpFlag
  4460.     RTS
  4461.  
  4462. mt_SetSpeed
  4463.     MOVEQ    #0,D0
  4464.     MOVE.B    3(A6),D0
  4465.     BEQ.W    mt_end
  4466.     CMP.B    #32,D0
  4467.     BHS.W    SetTempo
  4468.     CLR.B    mt_counter
  4469.     MOVE.B    D0,mt_speed
  4470.     RTS
  4471.  
  4472. mt_CheckMoreEfx
  4473.     BSR.W    mt_UpdateFunk
  4474.     MOVE.B    2(A6),D0
  4475.     AND.B    #$0F,D0
  4476.     CMP.B    #$9,D0
  4477.     BEQ.W    mt_SampleOffset
  4478.     CMP.B    #$B,D0
  4479.     BEQ.W    mt_PositionJump
  4480.     CMP.B    #$D,D0
  4481.     BEQ.S    mt_PatternBreak
  4482.     CMP.B    #$E,D0
  4483.     BEQ.S    mt_E_Commands
  4484.     CMP.B    #$F,D0
  4485.     BEQ.S    mt_SetSpeed
  4486.     CMP.B    #$C,D0
  4487.     BEQ.W    mt_VolumeChange
  4488.     BRA.W    mt_PerNop
  4489.  
  4490. mt_E_Commands
  4491.     MOVE.B    n_cmdlo(A6),D0
  4492.     AND.B    #$F0,D0
  4493.     LSR.B    #4,D0
  4494.     BEQ.S    mt_FilterOnOff
  4495.     CMP.B    #1,D0
  4496.     BEQ.W    mt_FinePortaUp
  4497.     CMP.B    #2,D0
  4498.     BEQ.W    mt_FinePortaDown
  4499.     CMP.B    #3,D0
  4500.     BEQ.S    mt_SetGlissControl
  4501.     CMP.B    #4,D0
  4502.     BEQ.W    mt_SetVibratoControl
  4503.     CMP.B    #5,D0
  4504.     BEQ.W    mt_SetFineTune
  4505.     CMP.B    #6,D0
  4506.     BEQ.W    mt_JumpLoop
  4507.     CMP.B    #7,D0
  4508.     BEQ.W    mt_SetTremoloControl
  4509.     CMP.B    #9,D0
  4510.     BEQ.W    mt_RetrigNote
  4511.     CMP.B    #$A,D0
  4512.     BEQ.W    mt_VolumeFineUp
  4513.     CMP.B    #$B,D0
  4514.     BEQ.W    mt_VolumeFineDown
  4515.     CMP.B    #$C,D0
  4516.     BEQ.W    mt_NoteCut
  4517.     CMP.B    #$D,D0
  4518.     BEQ.W    mt_NoteDelay
  4519.     CMP.B    #$E,D0
  4520.     BEQ.W    mt_PatternDelay
  4521.     CMP.B    #$F,D0
  4522.     BEQ.W    mt_FunkIt
  4523.     RTS
  4524.  
  4525. mt_FilterOnOff
  4526.     MOVE.B    n_cmdlo(A6),D0
  4527.     AND.B    #1,D0
  4528.     ASL.B    #1,D0
  4529.     AND.B    #$FD,$BFE001
  4530.     OR.B    D0,$BFE001
  4531.     RTS    
  4532.  
  4533. mt_SetGlissControl
  4534.     MOVE.B    n_cmdlo(A6),D0
  4535.     AND.B    #$0F,D0
  4536.     AND.B    #$F0,n_glissfunk(A6)
  4537.     OR.B    D0,n_glissfunk(A6)
  4538.     RTS
  4539.  
  4540. mt_SetVibratoControl
  4541.     MOVE.B    n_cmdlo(A6),D0
  4542.     AND.B    #$0F,D0
  4543.     AND.B    #$F0,n_wavecontrol(A6)
  4544.     OR.B    D0,n_wavecontrol(A6)
  4545.     RTS
  4546.  
  4547. mt_SetFineTune
  4548.     MOVE.B    n_cmdlo(A6),D0
  4549.     AND.B    #$0F,D0
  4550.     MOVE.B    D0,n_finetune(A6)
  4551.     RTS
  4552.  
  4553. mt_JumpLoop
  4554.     TST.B    mt_counter
  4555.     BNE.W    mt_Return
  4556.     MOVE.B    n_cmdlo(A6),D0
  4557.     AND.B    #$0F,D0
  4558.     BEQ.S    mt_SetLoop
  4559.     TST.B    n_loopcount(A6)
  4560.     BEQ.S    mt_jumpcnt
  4561.     SUBQ.B    #1,n_loopcount(A6)
  4562.     BEQ.W    mt_Return
  4563. mt_jmploop    MOVE.B    n_pattpos(A6),mt_PBreakPos
  4564.     ST    mt_PBreakFlag
  4565.     RTS
  4566.  
  4567. mt_jumpcnt
  4568.     MOVE.B    D0,n_loopcount(A6)
  4569.     BRA.S    mt_jmploop
  4570.  
  4571. mt_SetLoop
  4572.     MOVE.W    mt_PatternPos(PC),D0
  4573.     LSR.W    #4,D0
  4574.     MOVE.B    D0,n_pattpos(A6)
  4575.     RTS
  4576.  
  4577. mt_SetTremoloControl
  4578.     MOVE.B    n_cmdlo(A6),D0
  4579.     AND.B    #$0F,D0
  4580.     LSL.B    #4,D0
  4581.     AND.B    #$0F,n_wavecontrol(A6)
  4582.     OR.B    D0,n_wavecontrol(A6)
  4583.     RTS
  4584.  
  4585. mt_RetrigNote
  4586.     MOVE.L    D1,-(SP)
  4587.     MOVEQ    #0,D0
  4588.     MOVE.B    n_cmdlo(A6),D0
  4589.     AND.B    #$0F,D0
  4590.     BEQ.S    mt_rtnend
  4591.     MOVEQ    #0,D1
  4592.     MOVE.B    mt_counter(PC),D1
  4593.     BNE.S    mt_rtnskp
  4594.     MOVE.W    (A6),D1
  4595.     AND.W    #$0FFF,D1
  4596.     BNE.S    mt_rtnend
  4597.     MOVEQ    #0,D1
  4598.     MOVE.B    mt_counter(PC),D1
  4599. mt_rtnskp
  4600.     DIVU    D0,D1
  4601.     SWAP    D1
  4602.     TST.W    D1
  4603.     BNE.S    mt_rtnend
  4604. mt_DoRetrig
  4605.     MOVE.W    n_dmabit(A6),$DFF096    ; Channel DMA off
  4606.     MOVE.L    n_start(A6),(A5)    ; Set sampledata pointer
  4607.     MOVE.W    n_length(A6),4(A5)    ; Set length
  4608.     MOVE.W    #300,D0
  4609. mt_rtnloop1
  4610.     DBRA    D0,mt_rtnloop1
  4611.     MOVE.W    n_dmabit(A6),D0
  4612.     BSET    #15,D0
  4613.     MOVE.W    D0,$DFF096
  4614.     MOVE.W    #300,D0
  4615. mt_rtnloop2
  4616.     DBRA    D0,mt_rtnloop2
  4617.     MOVE.L    n_loopstart(A6),(A5)
  4618.     MOVE.L    n_replen(A6),4(A5)
  4619. mt_rtnend
  4620.     MOVE.L    (SP)+,D1
  4621.     RTS
  4622.  
  4623. mt_VolumeFineUp
  4624.     TST.B    mt_counter
  4625.     BNE.W    mt_Return
  4626.     MOVEQ    #0,D0
  4627.     MOVE.B    n_cmdlo(A6),D0
  4628.     AND.B    #$F,D0
  4629.     BRA.W    mt_VolSlideUp
  4630.  
  4631. mt_VolumeFineDown
  4632.     TST.B    mt_counter
  4633.     BNE.W    mt_Return
  4634.     MOVEQ    #0,D0
  4635.     MOVE.B    n_cmdlo(A6),D0
  4636.     AND.B    #$0F,D0
  4637.     BRA.W    mt_VolSlideDown2
  4638.  
  4639. mt_NoteCut
  4640.     MOVEQ    #0,D0
  4641.     MOVE.B    n_cmdlo(A6),D0
  4642.     AND.B    #$0F,D0
  4643.     CMP.B    mt_counter(PC),D0
  4644.     BNE.W    mt_Return
  4645.     CLR.B    n_volume(A6)
  4646.     MOVE.W    #0,8(A5)
  4647.     RTS
  4648.  
  4649. mt_NoteDelay
  4650.     MOVEQ    #0,D0
  4651.     MOVE.B    n_cmdlo(A6),D0
  4652.     AND.B    #$0F,D0
  4653.     CMP.B    mt_counter,D0
  4654.     BNE.W    mt_Return
  4655.     MOVE.W    (A6),D0
  4656.     BEQ.W    mt_Return
  4657.     MOVE.L    D1,-(SP)
  4658.     BRA.W    mt_DoRetrig
  4659.  
  4660. mt_PatternDelay
  4661.     TST.B    mt_counter
  4662.     BNE.W    mt_Return
  4663.     MOVEQ    #0,D0
  4664.     MOVE.B    n_cmdlo(A6),D0
  4665.     AND.B    #$0F,D0
  4666.     TST.B    mt_PattDelTime2
  4667.     BNE.W    mt_Return
  4668.     ADDQ.B    #1,D0
  4669.     MOVE.B    D0,mt_PattDelTime
  4670.     RTS
  4671.  
  4672. mt_FunkIt
  4673.     TST.B    mt_counter
  4674.     BNE.W    mt_Return
  4675.     MOVE.B    n_cmdlo(A6),D0
  4676.     AND.B    #$0F,D0
  4677.     LSL.B    #4,D0
  4678.     AND.B    #$0F,n_glissfunk(A6)
  4679.     OR.B    D0,n_glissfunk(A6)
  4680.     TST.B    D0
  4681.     BEQ.W    mt_Return
  4682. mt_UpdateFunk
  4683.     MOVEM.L    A0/D1,-(SP)
  4684.     MOVEQ    #0,D0
  4685.     MOVE.B    n_glissfunk(A6),D0
  4686.     LSR.B    #4,D0
  4687.     BEQ.S    mt_funkend
  4688.     LEA    mt_FunkTable(PC),A0
  4689.     MOVE.B    (A0,D0.W),D0
  4690.     ADD.B    D0,n_funkoffset(A6)
  4691.     BTST    #7,n_funkoffset(A6)
  4692.     BEQ.S    mt_funkend
  4693.     CLR.B    n_funkoffset(A6)
  4694.  
  4695.     MOVE.L    n_loopstart(A6),D0
  4696.     MOVEQ    #0,D1
  4697.     MOVE.W    n_replen(A6),D1
  4698.     ADD.L    D1,D0
  4699.     ADD.L    D1,D0
  4700.     MOVE.L    n_wavestart(A6),A0
  4701.     ADDQ.L    #1,A0
  4702.     CMP.L    D0,A0
  4703.     BLO.S    mt_funkok
  4704.     MOVE.L    n_loopstart(A6),A0
  4705. mt_funkok
  4706.     MOVE.L    A0,n_wavestart(A6)
  4707.     MOVEQ    #-1,D0
  4708.     SUB.B    (A0),D0
  4709.     MOVE.B    D0,(A0)
  4710. mt_funkend
  4711.     MOVEM.L    (SP)+,A0/D1
  4712.     RTS
  4713.  
  4714.  
  4715. mt_FunkTable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128
  4716.  
  4717. mt_VibratoTable    
  4718.     dc.b   0, 24, 49, 74, 97,120,141,161
  4719.     dc.b 180,197,212,224,235,244,250,253
  4720.     dc.b 255,253,250,244,235,224,212,197
  4721.     dc.b 180,161,141,120, 97, 74, 49, 24
  4722.  
  4723. mt_PeriodTable
  4724. ; Tuning 0, Normal
  4725.     dc.w    856,808,762,720,678,640,604,570,538,508,480,453
  4726.     dc.w    428,404,381,360,339,320,302,285,269,254,240,226
  4727.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  4728. ; Tuning 1
  4729.     dc.w    850,802,757,715,674,637,601,567,535,505,477,450
  4730.     dc.w    425,401,379,357,337,318,300,284,268,253,239,225
  4731.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  4732. ; Tuning 2
  4733.     dc.w    844,796,752,709,670,632,597,563,532,502,474,447
  4734.     dc.w    422,398,376,355,335,316,298,282,266,251,237,224
  4735.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  4736. ; Tuning 3
  4737.     dc.w    838,791,746,704,665,628,592,559,528,498,470,444
  4738.     dc.w    419,395,373,352,332,314,296,280,264,249,235,222
  4739.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  4740. ; Tuning 4
  4741.     dc.w    832,785,741,699,660,623,588,555,524,495,467,441
  4742.     dc.w    416,392,370,350,330,312,294,278,262,247,233,220
  4743.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  4744. ; Tuning 5
  4745.     dc.w    826,779,736,694,655,619,584,551,520,491,463,437
  4746.     dc.w    413,390,368,347,328,309,292,276,260,245,232,219
  4747.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  4748. ; Tuning 6
  4749.     dc.w    820,774,730,689,651,614,580,547,516,487,460,434
  4750.     dc.w    410,387,365,345,325,307,290,274,258,244,230,217
  4751.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  4752. ; Tuning 7
  4753.     dc.w    814,768,725,684,646,610,575,543,513,484,457,431
  4754.     dc.w    407,384,363,342,323,305,288,272,256,242,228,216
  4755.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  4756. ; Tuning -8
  4757.     dc.w    907,856,808,762,720,678,640,604,570,538,508,480
  4758.     dc.w    453,428,404,381,360,339,320,302,285,269,254,240
  4759.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  4760. ; Tuning -7
  4761.     dc.w    900,850,802,757,715,675,636,601,567,535,505,477
  4762.     dc.w    450,425,401,379,357,337,318,300,284,268,253,238
  4763.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  4764. ; Tuning -6
  4765.     dc.w    894,844,796,752,709,670,632,597,563,532,502,474
  4766.     dc.w    447,422,398,376,355,335,316,298,282,266,251,237
  4767.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  4768. ; Tuning -5
  4769.     dc.w    887,838,791,746,704,665,628,592,559,528,498,470
  4770.     dc.w    444,419,395,373,352,332,314,296,280,264,249,235
  4771.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  4772. ; Tuning -4
  4773.     dc.w    881,832,785,741,699,660,623,588,555,524,494,467
  4774.     dc.w    441,416,392,370,350,330,312,294,278,262,247,233
  4775.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  4776. ; Tuning -3
  4777.     dc.w    875,826,779,736,694,655,619,584,551,520,491,463
  4778.     dc.w    437,413,390,368,347,328,309,292,276,260,245,232
  4779.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  4780. ; Tuning -2
  4781.     dc.w    868,820,774,730,689,651,614,580,547,516,487,460
  4782.     dc.w    434,410,387,365,345,325,307,290,274,258,244,230
  4783.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  4784. ; Tuning -1
  4785.     dc.w    862,814,768,725,684,646,610,575,543,513,484,457
  4786.     dc.w    431,407,384,363,342,323,305,288,272,256,242,228
  4787.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  4788.  
  4789. mt_chan1temp    dc.l    0,0,0,0,0,$00010000,0,  0,0,0,0
  4790. mt_chan2temp    dc.l    0,0,0,0,0,$00020000,0,  0,0,0,0
  4791. mt_chan3temp    dc.l    0,0,0,0,0,$00040000,0,  0,0,0,0
  4792. mt_chan4temp    dc.l    0,0,0,0,0,$00080000,0,  0,0,0,0
  4793.  
  4794. mt_SampleStarts    dc.l    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  4795.         dc.l    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  4796.  
  4797. mt_SongDataPtr    dc.l 0
  4798. mt_speed    dc.b 6
  4799. mt_counter    dc.b 0
  4800. mt_SongPos    dc.b 0
  4801. mt_PBreakPos    dc.b 0
  4802. mt_PosJumpFlag    dc.b 0
  4803. mt_PBreakFlag    dc.b 0
  4804. mt_LowMask    dc.b 0
  4805. mt_PattDelTime    dc.b 0
  4806. mt_PattDelTime2    dc.b 0
  4807. mt_Enable    dc.b 0
  4808. mt_PatternPos    dc.w 0
  4809. mt_DMACONtemp    dc.w 0
  4810.  
  4811. ;/* End of File */
  4812.  
  4813.  
  4814.  
  4815. ; =============================================================================
  4816. ;
  4817. ;                                   D A T A
  4818. ;
  4819. ; =============================================================================
  4820.        
  4821. ; *****************************************************************************
  4822. ; Copperlist header
  4823. ; *****************************************************************************
  4824.  
  4825.     ALIGNQUAD
  4826.  
  4827. COL32    MACRO
  4828.     dc.l    $01800000,$01820000,$01840000,$01860000,$01880000,$018a0000
  4829.     dc.l    $018c0000,$018e0000,$01900000,$01920000,$01940000,$01960000
  4830.     dc.l    $01980000,$019a0000,$019c0000,$019e0000,$01a00000,$01a20000
  4831.     dc.l    $01a40000,$01a60000,$01a80000,$01aa0000,$01ac0000,$01ae0000
  4832.     dc.l    $01b00000,$01b20000,$01b40000,$01b60000,$01b80000,$01ba0000
  4833.     dc.l    $01bc0000,$01be0000
  4834.     ENDM
  4835.     
  4836. Cop
  4837.          dc.l     $01fc400f         ;FMODE   Bpl=3, Spr=3, ScanDouble (2x2)
  4838.          dc.l     $00968100           ;DMACON  Plane dma on line 0
  4839.          dc.l     $01000211         ;BPLCON0 Lores, 8 planes, ECS on 
  4840.          dc.l     $01020000        ;BPLCON1
  4841.          dc.l     $0104003f           ;BPLCON2 Sprite priority!
  4842.          dc.l     $01060020           ;BPLCON3 BBlank
  4843.          dc.l     $010c0000           ;BPLCON4 Sprite-colorbank (!)
  4844.          dc.l     $0108ffd8         ;BPL1MOD 2x2: modulo = -40
  4845.          dc.l     $010a0000        ;BPL2MOD
  4846.          dc.l     $008e2881         ;
  4847.          dc.l    $009028c1        ;
  4848.          dc.l     $00920038         ;
  4849.     dc.l     $009400a0        ;
  4850.  
  4851. CopBpl                    ; Bitplane pointers
  4852.          dc.l     $00e00000,$00e20000
  4853.          dc.l     $00e40000,$00e60002
  4854.          dc.l     $00e80000,$00ea0004
  4855.          dc.l     $00ec0000,$00ee0006
  4856.          dc.l     $00f00000,$00f20008
  4857.          dc.l     $00f40000,$00f6000a
  4858.          dc.l     $00f80000,$00fa000c
  4859.          dc.l     $00fc0000,$00fe000e
  4860.  
  4861. CopCol                    ; Colour registers (24 bit HL)
  4862.     dc.l    $01060c60        
  4863.     COL32
  4864.     dc.l    $01060e60        
  4865.     COL32
  4866.     dc.l    $01062c60        
  4867.     COL32
  4868.     dc.l    $01062e60
  4869.     COL32
  4870.     dc.l    $01064c60
  4871.     COL32
  4872.     dc.l    $01064e60
  4873.     COL32
  4874.     dc.l    $01066c60
  4875.     COL32
  4876.     dc.l    $01066e60
  4877.     COL32
  4878.     dc.l    $01068c60
  4879.     COL32
  4880.     dc.l    $01068e60
  4881.     COL32
  4882.     dc.l    $0106ac60
  4883.     COL32
  4884.     dc.l    $0106ae60
  4885.     COL32
  4886.     dc.l    $0106cc60
  4887.     COL32
  4888.     dc.l    $0106ce60
  4889.     COL32
  4890.     dc.l    $0106ec60
  4891.     COL32
  4892.     dc.l    $0106ee60
  4893.     COL32
  4894.  
  4895. CopEnd
  4896.  
  4897.  
  4898. ; *****************************************************************************
  4899. ; Variables 
  4900. ; *****************************************************************************
  4901.  
  4902.     ALIGNLONG
  4903.  
  4904. Joy1Left    dc.b     0        ; Joystick direction
  4905. Joy1Right    dc.b    0
  4906. Joy1Up        dc.b    0
  4907. Joy1Down    dc.b    0
  4908. Joy1Fire    dc.b    0
  4909.  
  4910. KeyRaw        dc.b    0        ; Raw code of last pressed key
  4911. KeyState    dc.b    0         ; State of last pressed key
  4912.  
  4913.     ALIGNLONG
  4914.  
  4915. RendCh        dc.l    0        ; }_ Chunky buffer
  4916. DispCh        dc.l    0        ; }
  4917. RendBL        dc.l    0        ; }_ Blitterlist
  4918. DispBL        dc.l    0        ; }
  4919. RendCop        dc.l    0         ; }_ Copperlist
  4920. DispCop        dc.l    0        ; }
  4921.  
  4922. Plyr_Z        dc.l    0        ; Z-position
  4923. Plyr_ZSpd    dc.w    0        ; Tunnel scroll speed (in texels)
  4924. Plyr_Scroll    dc.w    0        ; Tunnel scroll position (in texels)
  4925. Plyr_X        dc.w    0        ; }_ Center-coordinates of player ship
  4926. Plyr_Y        dc.w    0        ; }
  4927. Plyr_XSpd    dc.w    0        ; }_ Speed
  4928. Plyr_YSpd    dc.w    0        ; }
  4929. Plyr_Level    dc.w    0        ; Current level number
  4930. Plyr_Ships    dc.w    0        ; Number of remaining ships
  4931. Plyr_Time    dc.l    0        ; Time left for this level
  4932. Plyr_Frame    dc.w    0        ; Animation frame number
  4933. Plyr_EngineCnt    dc.w    0        ; Engine colour counter
  4934. Plyr_EngineOn    dc.w    0        ; True is engine is on, false if off
  4935. Plyr_Name    dcb.b    MaxStrLen+1,0    ; Name of player
  4936. Plyr_Cheat    dc.b    0        ; Cheatmode on / off
  4937.  
  4938.         ALIGNLONG
  4939.         
  4940. Game_Flags    dc.l    0        ; Game-loop status flags
  4941. Game_FirstWall    dc.w    0        ; Number of first visible wall
  4942. Game_LastWall    dc.w    0        ; Number of last visible wall
  4943. Game_WallZ    dc.l    0        ; Pointer to Wall_Z array
  4944. Game_WallType    dc.l    0        ; Pointer to Wall_Type array
  4945. Game_LevelPtr    dc.l    0        ; Pointer to Level array
  4946.  
  4947. Toggle        dc.l    0        ; Toggles between 0 and 1 
  4948. ToggleCnt    dc.l    0        ; Time depends on max. ToggleCnt
  4949.  
  4950. FlgTimer    dc.l    0        ; Gameloop statusflag timer thing
  4951.  
  4952. BestTimes    dcb.l    9,0        ; Best track times
  4953. BestNames    dcb.b    9*12,0        ; Names of best racers
  4954.  
  4955. RealTimeCnt    dc.l    0        ; RealTime counter
  4956. RealTime    dc.l    0        ; RealTime value
  4957.         
  4958. Intro_Timer    dc.l    0        ; Intro timer
  4959. Intro_Flags    dc.l    0        ; Intro status-flags
  4960. Intro_WarpIn    dc.b    0        ; Intro warp-in is active
  4961. Intro_WarpOut    dc.b    0        ; Intro warp-out is active
  4962. Intro_WarpCount    dc.w    0        ; Intro warp-in/out counter
  4963. Intro_Level    dc.w    0        ; Levelnr for Track Select
  4964.  
  4965.  
  4966.  
  4967. ; *****************************************************************************
  4968. ; Level Data
  4969. ; *****************************************************************************
  4970.  
  4971.     ALIGNLONG
  4972.  
  4973. Level        ; Level 1 -----------------------------------------------------
  4974.         dc.w    34,3        ; NumWalls, Ships
  4975.         dc.l    1500        ; Time
  4976.         ; Level 2 -----------------------------------------------------
  4977.         dc.w    34,4
  4978.         dc.l    1500
  4979.         ; Level 3 -----------------------------------------------------
  4980.         dc.w    34,2
  4981.         dc.l    1000
  4982.         ; Level 4 -----------------------------------------------------
  4983.         dc.w    14,1
  4984.         dc.l    500
  4985.         ; Level 5 -----------------------------------------------------
  4986.         dc.w    50,3
  4987.         dc.l    2000
  4988.  
  4989. Wall_Z        ; Level 1 -----------------------------------------------------
  4990.         dc.l    512
  4991.         dc.l    01*1024,02*1024,03*1024,04*1024
  4992.         dc.l    05*1024,06*1024,07*1024,08*1024
  4993.         dc.l    09*1024,10*1024,11*1024,12*1024
  4994.         dc.l    13*1024,14*1024,15*1024,16*1024
  4995.         dc.l    17*1024,18*1024,19*1024,20*1024
  4996.         dc.l    21*1024,22*1024,23*1024,24*1024
  4997.         dc.l    25*1024,26*1024,27*1024,28*1024
  4998.         dc.l    29*1024,30*1024,31*1024,32*1024
  4999.         dc.l    33*1024
  5000.         dcb.l    MaxWall-34,0
  5001.         ; Level 2 -----------------------------------------------------
  5002.         dc.l    512
  5003.         dc.l    04*512,05*512,06*512,07*512
  5004.         dc.l    10*512,11*512,12*512,13*512
  5005.         dc.l    16*512,17*512,18*512,19*512
  5006.         dc.l    22*512,23*512,24*512,25*512
  5007.         dc.l    28*512,29*512,30*512,31*512
  5008.         dc.l    32*512,33*512,34*512,35*512
  5009.         dc.l    36*512,37*512,38*512,39*512
  5010.         dc.l    40*512,41*512,42*512,43*512
  5011.         dc.l    46*512
  5012.         dcb.l    MaxWall-34,0
  5013.         ; Level 3 -----------------------------------------------------
  5014.         dc.l    512
  5015.         dc.l    02*512,03*512,05*512,06*512
  5016.         dc.l    08*512,09*512,11*512,12*512
  5017.         dc.l    14*512,15*512,17*512,18*512
  5018.         dc.l    20*512,21*512,23*512,24*512
  5019.         dc.l    26*512,27*512,29*512,30*512
  5020.         dc.l    32*512,33*512,35*512,36*512
  5021.         dc.l    38*512,39*512,41*512,42*512
  5022.         dc.l    44*512,45*512,47*512,48*512
  5023.         dc.l    50*512
  5024.         dcb.l    MaxWall-34,0
  5025.         ; Level 4 -----------------------------------------------------
  5026.         dc.l    512
  5027.         dc.l    04*512,05*512,11*256,06*512
  5028.         dc.l    07*512,08*512,17*256,09*512
  5029.         dc.l    10*512,11*512,23*256,12*512
  5030.         dc.l    14*512
  5031.         dcb.l    MaxWall-14,0
  5032.         ; Level 5 -----------------------------------------------------
  5033.         dc.l    512
  5034.         dc.l    02*512,04*512,05*512,05*512+256
  5035.         dc.l    08*512,09*512,12*512,13*512
  5036.         dc.l    16*512,18*512,19*512,19*512+256
  5037.         dc.l    22*512,23*512,26*512,27*512
  5038.         dc.l    30*512,31*512,32*512,33*512
  5039.         dc.l    34*512,35*512,36*512,37*512
  5040.         dc.l    40*512,41*512,42*512,43*512
  5041.         dc.l    44*512,45*512,46*512,47*512
  5042.         dc.l    50*512,51*512,51*512+256,51*512+256+128
  5043.         dc.l    52*512,52*512+256,53*512,53*512+256
  5044.         dc.l    54*512,55*512,55*512+256,55*512+256+128
  5045.         dc.l    56*512,56*512+256,57*512,57*512+256
  5046.         dc.l    60*512
  5047.         dcb.l    MaxWall-50,0
  5048.  
  5049. Wall_Type    ; Level 1 -----------------------------------------------------
  5050.         dc.w    WT_Start
  5051.         dc.w    WT_Left,WT_Left,WT_Left,WT_Left
  5052.         dc.w    WT_Right,WT_Right,WT_Right,WT_Right
  5053.         dc.w    WT_Left,WT_Left,WT_Right,WT_Right
  5054.         dc.w    WT_Left,WT_Left,WT_Right,WT_Right
  5055.         dc.w    WT_Up,WT_Up,WT_Down,WT_Down
  5056.         dc.w    WT_Up,WT_Up,WT_Down,WT_Down
  5057.         dc.w    WT_Up,WT_Down,WT_Up,WT_Down
  5058.         dc.w    WT_Up,WT_Down,WT_Up,WT_Down
  5059.         dc.w    WT_Finish
  5060.         dcb.w    MaxWall-34,0
  5061.         ; Level 2 -----------------------------------------------------
  5062.         dc.w    WT_Start
  5063.         dc.w    WT_Left,WT_Up,WT_Right,WT_Down
  5064.         dc.w    WT_Up,WT_Left,WT_Down,WT_Right
  5065.         dc.w    WT_Right,WT_Up,WT_Down,WT_Left
  5066.         dc.w    WT_Down,WT_Left,WT_Right,WT_Up
  5067.         dc.w    WT_Left,WT_Up,WT_Right,WT_Down
  5068.         dc.w    WT_Up,WT_Left,WT_Down,WT_Right
  5069.         dc.w    WT_Right,WT_Up,WT_Down,WT_Left
  5070.         dc.w    WT_Down,WT_Left,WT_Right,WT_Up
  5071.         dc.w    WT_Finish
  5072.         dcb.w    MaxWall-34,0
  5073.         ; Level 3 -----------------------------------------------------
  5074.         dc.w    WT_Start
  5075.         dc.w    WT_Right,WT_Up,WT_Left,WT_Down
  5076.         dc.w    WT_Right,WT_Up,WT_Left,WT_Down
  5077.         dc.w    WT_Left,WT_Up,WT_Right,WT_Down
  5078.         dc.w    WT_Left,WT_Up,WT_Right,WT_Down
  5079.         dc.w    WT_Right,WT_Down,WT_Left,WT_Up
  5080.         dc.w    WT_Right,WT_Down,WT_Left,WT_Up
  5081.         dc.w    WT_Left,WT_Down,WT_Right,WT_Up
  5082.         dc.w    WT_Left,WT_Down,WT_Right,WT_Up
  5083.         dc.w    WT_Finish
  5084.         dcb.w    MaxWall-34,0
  5085.         ; Level 4 -----------------------------------------------------
  5086.         dc.w    WT_Start
  5087.         dc.w    WT_Down,WT_Up,WT_Left,WT_Down
  5088.         dc.w    WT_Up,WT_Down,WT_Right,WT_Up
  5089.         dc.w    WT_Down,WT_Up,WT_Left,WT_Right
  5090.         dc.w    WT_Finish
  5091.         dcb.w    MaxWall-14,0
  5092.         ; Level 5 -----------------------------------------------------
  5093.         dc.w    WT_Start
  5094.         dc.w    WT_Left,WT_Down,WT_Up,WT_Right
  5095.         dc.w    WT_Left,WT_Right,WT_Left,WT_Right
  5096.         dc.w    WT_Left,WT_Down,WT_Up,WT_Right
  5097.         dc.w    WT_Down,WT_Up,WT_Down,WT_Up
  5098.         dc.w    WT_Right,WT_Right,WT_Down,WT_Up
  5099.         dc.w    WT_Left,WT_Left,WT_Up,WT_Up
  5100.         dc.w    WT_Right,WT_Right,WT_Up,WT_Down
  5101.         dc.w    WT_Left,WT_Left,WT_Up,WT_Up
  5102.         dc.w    WT_Left,WT_Down,WT_Up,WT_Right
  5103.         dc.w    WT_Left,WT_Right,WT_Left,WT_Right
  5104.         dc.w    WT_Left,WT_Down,WT_Up,WT_Right
  5105.         dc.w    WT_Down,WT_Up,WT_Down,WT_Up
  5106.         dc.w    WT_Finish
  5107.         dcb.w    MaxWall-50,0                
  5108.  
  5109.  
  5110. ; *****************************************************************************
  5111. ; Constant data
  5112. ; *****************************************************************************
  5113.  
  5114.         ALIGNLONG
  5115.         
  5116. Type_Bitmap    dc.l    wt_start        ; Pointers to bitmaps
  5117.         dc.l    wt_finish
  5118.         dc.l    wt_left
  5119.         dc.l    wt_right
  5120.         dc.l    wt_up
  5121.         dc.l    wt_down
  5122.         
  5123. Type_Hole    dc.w    0,0,159,127        ; WT_Start
  5124.         dc.w    0,0,159,127        ; WT_Finish
  5125.         dc.w    80,0,159,127        ; WT_Left
  5126.         dc.w    0,0,79,127        ; WT_Right
  5127.         dc.w    0,64,159,127        ; WT_Up
  5128.         dc.w    0,0,159,63        ; WT_Down
  5129.  
  5130. Ship_Anim    dc.l     Ship01,Ship02,Ship03,Ship04,Ship05    ; Pointers to
  5131.         dc.l     Ship06,Ship07,Ship08,Ship09,Ship10    ; animation
  5132.         dc.l     Ship11,Ship12,Ship13,Ship14,Ship15    ; frames
  5133.         dc.l     Ship16,Ship17,Ship18,Ship19,Ship20    ;
  5134.         dc.l     Ship21,Ship22,Ship23,Ship24,Ship25    ;
  5135.  
  5136. Shadow_Anim    dc.l    Shadow01,Shadow02,Shadow03,Shadow04    ; Pointers to
  5137.         dc.l    Shadow05                ; anim frames
  5138.  
  5139. Coll_Bounds    dc.w    -21,-10,20,9,    -20,-10,20,9    ; Collision
  5140.         dc.w    -19,-10,20,9,    -20,-10,20,9    ; boundaries
  5141.         dc.w    -20,-10,21,9,    -21,-8,20,7    ; for player ship
  5142.         dc.w    -19,-8,20,7,    -19,-8,19,6    
  5143.         dc.w    -20,-8,19,7,    -20,-8,21,7
  5144.         dc.w    -20,-7,21,7,    -19,-7,20,6
  5145.         dc.w    -19,-7,19,6,    -20,-7,19,6
  5146.         dc.w    -21,-7,20,7,    -20,-12,20,10
  5147.         dc.w    -19,-12,20,9,    -19,-12,20,8
  5148.         dc.w    -20,-12,19,9,    -20,-12,20,10
  5149.         dc.w    -20,-12,20,13,    -19,-12,19,12
  5150.         dc.w    -19,-12,20,11,    -19,-12,19,12
  5151.         dc.w    -20,-12,20,13
  5152.         
  5153. Raw2ASCII    dc.b    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0           ; 00..0F
  5154.         dc.b    81,87,69,82,84,89,85,73,79,80,0,0,0,0,0,0  ; 10..1F
  5155.         dc.b    65,83,68,70,71,72,74,75,76,00,0,0,0,0,0,0  ; 20..2F
  5156.         dc.b    00,90,88,67,86,66,78,77,00,00,0,0,0,0,0,0  ; 30..3F
  5157.         dc.b    32                       ; 40
  5158.  
  5159. ; *****************************************************************************
  5160. ; Graphics, text, etc...
  5161. ; *****************************************************************************
  5162.  
  5163.     ALIGNLONG
  5164.     
  5165.     incdir "fantasy:tunn3l/inc/"
  5166.  
  5167. TxtLut        incbin     "Txt.LUT"        ; 160x128x2 Texture LookUpTable
  5168. WallLut_S    incbin     "Wall_S.LUT"        ; }
  5169. WallLut_X    incbin     "Wall_X.LUT"        ; }- 2048x4 Wall LookUpTable 
  5170. WallLut_Y    incbin     "Wall_Y.LUT"            ; }
  5171.  
  5172. txt        incbin     "TunnelTxt.CKY"        ; 256x256 tunnel texture
  5173.  
  5174. Ship01        incbin    "Ship01.CKY"        ; 48x25 ship images
  5175. Ship02        incbin    "Ship02.CKY"        ; 
  5176. Ship03        incbin    "Ship03.CKY"        ; 
  5177. Ship04        incbin    "Ship04.CKY"        ; 
  5178. Ship05        incbin    "Ship05.CKY"        ; 
  5179. Ship06        incbin    "Ship06.CKY"        ; 
  5180. Ship07        incbin    "Ship07.CKY"        ; 
  5181. Ship08        incbin    "Ship08.CKY"        ; 
  5182. Ship09        incbin    "Ship09.CKY"        ; 
  5183. Ship10        incbin    "Ship10.CKY"        ; 
  5184. Ship11        incbin    "Ship11.CKY"        ; 
  5185. Ship12        incbin    "Ship12.CKY"        ; 
  5186. Ship13        incbin    "Ship13.CKY"        ; 
  5187. Ship14        incbin    "Ship14.CKY"        ; 
  5188. Ship15        incbin    "Ship15.CKY"        ; 
  5189. Ship16        incbin    "Ship16.CKY"        ; 
  5190. Ship17        incbin    "Ship17.CKY"        ; 
  5191. Ship18        incbin    "Ship18.CKY"        ; 
  5192. Ship19        incbin    "Ship19.CKY"        ; 
  5193. Ship20        incbin    "Ship20.CKY"        ; 
  5194. Ship21        incbin    "Ship21.CKY"        ; 
  5195. Ship22        incbin    "Ship22.CKY"        ; 
  5196. Ship23        incbin    "Ship23.CKY"        ; 
  5197. Ship24        incbin    "Ship24.CKY"        ; 
  5198. Ship25        incbin    "Ship25.CKY"        ; 
  5199.  
  5200. Shadow01    incbin    "Shadow01.CKY"        ; 48x25 shadow images
  5201. Shadow02    incbin    "Shadow02.CKY"        ;
  5202. Shadow03    incbin    "Shadow03.CKY"        ;
  5203. Shadow04    incbin    "Shadow04.CKY"        ;
  5204. Shadow05    incbin    "Shadow05.CKY"        ;
  5205.  
  5206. wt_start    incbin     "WT_Start.CKY"        ; Wall graphics
  5207. wt_finish    incbin     "WT_Finish.CKY"        ;
  5208. wt_left        incbin     "WT_Left.CKY"        ;
  5209. wt_right    incbin     "WT_Right.CKY"        ;
  5210. wt_up        incbin     "WT_Up.CKY"        ;
  5211. wt_down        incbin     "WT_Down.CKY"        ;
  5212.  
  5213. IntroPal    incbin     "IntroPal.PAL"        ; Intro palette (24-bit)
  5214. GamePal        incbin  "GamePal.PAL"        ; Game palette (24-bit)
  5215. EnginePal    incbin    "EnginePal.PAL"        ; Engine colour palette
  5216.  
  5217. WhitePal    dcb.l    256,$00ffffff        ; Totally white palette
  5218. TempPal        dcb.l    256,$00000000        ; Temporary palette for fades
  5219.  
  5220. IntroWarp    incbin     "IntroWarp.LUT"        ; Warp LookUpTable
  5221. IntroFont    incbin     "IntroFont.RAW"        ; Intro font graphics
  5222.  
  5223. ChunkyFont    incbin    "ChunkyFont.CKY"    ; Game font
  5224.  
  5225. txt_track    dc.b    "TRACK",0        ; Texts
  5226. txt_complete    dc.b    "COMPLETE",0
  5227. txt_out        dc.b    "OUT",0
  5228. txt_of        dc.b    "OF",0
  5229. txt_time    dc.b    "TIME",0
  5230. txt_ships    dc.b    "SHIPS",0
  5231. txt_press    dc.b    "PRESS",0
  5232. txt_fire    dc.b    "FIRE",0
  5233. txt_race    dc.b    "RACE",0
  5234. txt_over    dc.b    "OVER",0
  5235. txt_best    dc.b     "BEST",0
  5236. txt_pause    dc.b    "PAUSE",0
  5237.  
  5238. itxt_0        dc.b    "    ZERO GRAVITY",0    ; Intro texts
  5239. itxt_1        dc.b    "   **************",0
  5240. itxt_2        dc.b    "     CREATED BY",0
  5241. itxt_3        dc.b    " MATTHIJS HOLLEMANS",0
  5242. itxt_4        dc.b    "       @ 1997",0
  5243. itxt_5        dc.b    "  #[[[[[[[[[[[[[[$",0
  5244. itxt_6        dc.b    "  \ FIRE = START _",0
  5245. itxt_7        dc.b    "  \ ESC  =  QUIT _",0
  5246. itxt_8        dc.b    "  &]]]]]]]]]]]]]];",0
  5247.  
  5248. itxt_10        dc.b    "     INTRO MUSIC",0
  5249. itxt_11        dc.b    "     ZOLTAR/DOOM",0
  5250. itxt_12        dc.b    "    IN-GAME MUSIC",0
  5251. itxt_13        dc.b    "        RADIUM",0
  5252. itxt_14        dc.b    "     C2P CODE BY",0
  5253. itxt_15        dc.b    "   JUERGEN FISCHER",0
  5254. itxt_19        dc.b    "   [[[[[[[[[[[[[[[",0
  5255.  
  5256. itxt_20        dc.b    "  #[[[[[[[[[[[[[[$",0
  5257. itxt_21        dc.b    "  \ HALL OF FAME _",0
  5258. itxt_22        dc.b    "  &]]]]]]]]]]]]]];",0
  5259.  
  5260. ian_0        dc.b    "   ENTER YOUR NAME",0
  5261. ian_1        dc.b    "   #[[[[[[[[[[[[[$",0
  5262. ian_2        dc.b    "   \             _",0
  5263. ian_3        dc.b    "   &]]]]]]]]]]]]];",0
  5264.  
  5265. its_0        dc.b    "  #[[[[[[[[[[[[[[$",0
  5266. its_1        dc.b    "  \ TRACK SELECT _",0
  5267. its_2        dc.b    "  &]]]]]]]]]]]]]];",0
  5268.  
  5269. its_3        dc.b    "     TRACK    0",0
  5270. its_4        dc.b    "     TIME  0:00",0
  5271. its_5        dc.b    "     SHIPS    0",0
  5272.  
  5273. its_6        dc.b    "    BEST TIME BY",0
  5274. its_7        dc.b    "#[[[[[[[[[[[[[[[[[[$",0
  5275. its_8        dc.b    "\ FIRE  =     PLAY _",0
  5276. its_9        dc.b    "\ LEFT  = PREVIOUS _",0
  5277. its_10        dc.b    "\ RIGHT =     NEXT _",0
  5278. its_11        dc.b    "&]]]]]]]]]]]]]]]]]];",0
  5279.  
  5280.  
  5281. version        dc.b    "$VER: ZeroGravity 1.0 (C) 1997 Matthijs Hollemans",0
  5282.  
  5283.  
  5284. ; =============================================================================
  5285. ;
  5286. ;                                C H I P D A T A
  5287. ;
  5288. ; =============================================================================
  5289.  
  5290.     SECTION    ChipData,DATA_C
  5291.  
  5292. ; *****************************************************************************
  5293. ; Intro copperlist
  5294. ; *****************************************************************************
  5295.     
  5296. IntroCop
  5297.         dc.l     $01fc0000         ;FMODE   
  5298.     
  5299.          dc.l     $01000210         ;BPLCON0 Lores, 8 planes
  5300.          dc.l     $01020000        ;BPLCON1
  5301.          dc.l     $01040000           ;BPLCON2
  5302.          dc.l     $01060000           ;BPLCON3
  5303.          dc.l     $01080000         ;BPL1MOD
  5304.          dc.l     $010a0000        ;BPL2MOD
  5305.          dc.l     $010c0000           ;BPLCON4
  5306.          dc.l     $008e2c81         ;
  5307.          dc.l    $00902cc1        ;
  5308.          dc.l     $00920038         ;
  5309.     dc.l     $009400d0        ;
  5310.  
  5311. IntroCopBpl                ; Bitplane pointers
  5312.          dc.l     $00e00000,$00e20000    
  5313.          dc.l     $00e40000,$00e60000
  5314.          dc.l     $00e80000,$00ea0000
  5315.          dc.l     $00ec0000,$00ee0000
  5316.          dc.l     $00f00000,$00f20000
  5317.          dc.l     $00f40000,$00f60000
  5318.          dc.l     $00f80000,$00fa0000
  5319.          dc.l     $00fc0000,$00fe0000
  5320.  
  5321. IntroCopCol                ; Colour registers (24 bit HL)
  5322.     dc.l    $01060c40        ; Bank0, Hi 12-bits
  5323.     COL32
  5324.     dc.l    $01060e40        ; Bank0, Lo 12-bits
  5325.     COL32
  5326.     dc.l    $01062c40        ; Bank1, Hi 12-bits
  5327.     COL32
  5328.     dc.l    $01062e40        ; Bank1, Lo 12-bits
  5329.     COL32
  5330.     dc.l    $01064c40        ; etc...
  5331.     COL32
  5332.     dc.l    $01064e40
  5333.     COL32
  5334.     dc.l    $01066c40
  5335.     COL32
  5336.     dc.l    $01066e40
  5337.     COL32
  5338.     dc.l    $01068c40
  5339.     COL32
  5340.     dc.l    $01068e40
  5341.     COL32
  5342.     dc.l    $0106ac40
  5343.     COL32
  5344.     dc.l    $0106ae40
  5345.     COL32
  5346.     dc.l    $0106cc40
  5347.     COL32
  5348.     dc.l    $0106ce40
  5349.     COL32
  5350.     dc.l    $0106ec40
  5351.     COL32
  5352.     dc.l    $0106ee40
  5353.     COL32
  5354.  
  5355. IntroCopSpr
  5356.     dc.l    $01200000,$01220000,$01240000,$01260000    
  5357.     dc.l    $01280000,$012a0000,$012c0000,$012e0000    
  5358.     dc.l    $01300000,$01320000,$01340000,$01360000
  5359.     dc.l    $01380000,$013a0000,$013c0000,$013e0000
  5360.  
  5361. IntroCopRainbow
  5362.     dc.l    $2c0ffffe,$1060c40,$1be0346,$1060e40,$1be07b0    ; StartY=44
  5363.     dc.l    $2d0ffffe,$1060c40,$1be0345,$1060e40,$1be06ae
  5364.     dc.l    $2e0ffffe,$1060c40,$1be0345,$1060e40,$1be059d
  5365.     dc.l    $2f0ffffe,$1060c40,$1be0345,$1060e40,$1be048c
  5366.     dc.l    $300ffffe,$1060c40,$1be0345,$1060e40,$1be047b
  5367.     dc.l    $310ffffe,$1060c40,$1be0345,$1060e40,$1be0369
  5368.     dc.l    $320ffffe,$1060c40,$1be0345,$1060e40,$1be0258
  5369.     dc.l    $330ffffe,$1060c40,$1be0345,$1060e40,$1be0247
  5370.     dc.l    $340ffffe,$1060c40,$1be0345,$1060e40,$1be0136
  5371.     dc.l    $350ffffe,$1060c40,$1be0345,$1060e40,$1be0025
  5372.     dc.l    $360ffffe,$1060c40,$1be0345,$1060e40,$1be0013
  5373.     dc.l    $370ffffe,$1060c40,$1be0245,$1060e40,$1be0f02
  5374.     dc.l    $380ffffe,$1060c40,$1be0235,$1060e40,$1be0ef1
  5375.     dc.l    $390ffffe,$1060c40,$1be0235,$1060e40,$1be0de0
  5376.     dc.l    $3a0ffffe,$1060c40,$1be0234,$1060e40,$1be0dde
  5377.     dc.l    $3b0ffffe,$1060c40,$1be0234,$1060e40,$1be0ccd
  5378.     dc.l    $3c0ffffe,$1060c40,$1be0234,$1060e40,$1be0bbc
  5379.     dc.l    $3d0ffffe,$1060c40,$1be0234,$1060e40,$1be0bab
  5380.     dc.l    $3e0ffffe,$1060c40,$1be0234,$1060e40,$1be0a9a
  5381.     dc.l    $3f0ffffe,$1060c40,$1be0234,$1060e40,$1be0988
  5382.     dc.l    $400ffffe,$1060c40,$1be0234,$1060e40,$1be0987
  5383.     dc.l    $410ffffe,$1060c40,$1be0234,$1060e40,$1be0876
  5384.     dc.l    $420ffffe,$1060c40,$1be0234,$1060e40,$1be0765
  5385.     dc.l    $430ffffe,$1060c40,$1be0234,$1060e40,$1be0754
  5386.     dc.l    $440ffffe,$1060c40,$1be0234,$1060e40,$1be0642
  5387.     dc.l    $450ffffe,$1060c40,$1be0234,$1060e40,$1be0531
  5388.     dc.l    $460ffffe,$1060c40,$1be0234,$1060e40,$1be0420
  5389.     dc.l    $470ffffe,$1060c40,$1be0233,$1060e40,$1be041f
  5390.     dc.l    $480ffffe,$1060c40,$1be0233,$1060e40,$1be030d
  5391.     dc.l    $490ffffe,$1060c40,$1be0223,$1060e40,$1be02fc
  5392.     dc.l    $4a0ffffe,$1060c40,$1be0223,$1060e40,$1be02eb
  5393.     dc.l    $4b0ffffe,$1060c40,$1be0223,$1060e40,$1be01da
  5394.     dc.l    $4c0ffffe,$1060c40,$1be0223,$1060e40,$1be00c9
  5395.     dc.l    $4d0ffffe,$1060c40,$1be0223,$1060e40,$1be00b7
  5396.     dc.l    $4e0ffffe,$1060c40,$1be0123,$1060e40,$1be0fa6
  5397.     dc.l    $4f0ffffe,$1060c40,$1be0123,$1060e40,$1be0e95
  5398.     dc.l    $500ffffe,$1060c40,$1be0123,$1060e40,$1be0d84
  5399.     dc.l    $510ffffe,$1060c40,$1be0123,$1060e40,$1be0d73
  5400.     dc.l    $520ffffe,$1060c40,$1be0123,$1060e40,$1be0c61
  5401.     dc.l    $530ffffe,$1060c40,$1be0123,$1060e40,$1be0b50
  5402.     dc.l    $540ffffe,$1060c40,$1be0122,$1060e40,$1be0b5f
  5403.     dc.l    $550ffffe,$1060c40,$1be0122,$1060e40,$1be0a4e
  5404.     dc.l    $560ffffe,$1060c40,$1be0122,$1060e40,$1be093c
  5405.     dc.l    $570ffffe,$1060c40,$1be0122,$1060e40,$1be092b
  5406.     dc.l    $580ffffe,$1060c40,$1be0122,$1060e40,$1be081a
  5407.     dc.l    $590ffffe,$1060c40,$1be0122,$1060e40,$1be0709
  5408.     dc.l    $5a0ffffe,$1060c40,$1be0112,$1060e40,$1be07f8
  5409.     dc.l    $5b0ffffe,$1060c40,$1be0112,$1060e40,$1be06e6
  5410.     dc.l    $5c0ffffe,$1060c40,$1be0112,$1060e40,$1be05d5
  5411.     dc.l    $5d0ffffe,$1060c40,$1be0112,$1060e40,$1be04c4
  5412.     dc.l    $5e0ffffe,$1060c40,$1be0112,$1060e40,$1be04b3
  5413.     dc.l    $5f0ffffe,$1060c40,$1be0112,$1060e40,$1be03a2
  5414.     dc.l    $600ffffe,$1060c40,$1be0112,$1060e40,$1be0290
  5415.     dc.l    $610ffffe,$1060c40,$1be0111,$1060e40,$1be028f
  5416.     dc.l    $620ffffe,$1060c40,$1be0111,$1060e40,$1be017e
  5417.     dc.l    $630ffffe,$1060c40,$1be0111,$1060e40,$1be006d
  5418.     dc.l    $640ffffe,$1060c40,$1be0111,$1060e40,$1be005b
  5419.     dc.l    $650ffffe,$1060c40,$1be0011,$1060e40,$1be0f4a
  5420.     dc.l    $660ffffe,$1060c40,$1be0011,$1060e40,$1be0e39
  5421.     dc.l    $670ffffe,$1060c40,$1be0011,$1060e40,$1be0d28
  5422.     dc.l    $680ffffe,$1060c40,$1be0011,$1060e40,$1be0d27
  5423.     dc.l    $690ffffe,$1060c40,$1be0011,$1060e40,$1be0c15
  5424.     dc.l    $6a0ffffe,$1060c40,$1be0011,$1060e40,$1be0b04
  5425.     dc.l    $6b0ffffe,$1060c40,$1be0001,$1060e40,$1be0bf3
  5426.     dc.l    $6c0ffffe,$1060c40,$1be0001,$1060e40,$1be0ae2
  5427.     dc.l    $6d0ffffe,$1060c40,$1be0001,$1060e40,$1be09d1
  5428.     dc.l    $6e0ffffe,$1060c40,$1be0000,$1060e40,$1be09cf
  5429.     dc.l    $6f0ffffe,$1060c40,$1be0000,$1060e40,$1be08be
  5430.     dc.l    $700ffffe,$1060c40,$1be0000,$1060e40,$1be07ad
  5431.     dc.l    $710ffffe,$1060c40,$1be0000,$1060e40,$1be079c
  5432.     dc.l    $720ffffe,$1060c40,$1be0000,$1060e40,$1be068a
  5433.     dc.l    $730ffffe,$1060c40,$1be0000,$1060e40,$1be0579
  5434.     dc.l    $740ffffe,$1060c40,$1be0000,$1060e40,$1be0468
  5435.     dc.l    $750ffffe,$1060c40,$1be0000,$1060e40,$1be0457
  5436.     dc.l    $760ffffe,$1060c40,$1be0000,$1060e40,$1be0346
  5437.     dc.l    $770ffffe,$1060c40,$1be0000,$1060e40,$1be0234
  5438.     dc.l    $780ffffe,$1060c40,$1be0000,$1060e40,$1be0223
  5439.     dc.l    $790ffffe,$1060c40,$1be0000,$1060e40,$1be0112
  5440.     dc.l    $7a0ffffe,$1060c40,$1be0000,$1060e40,$1be0001
  5441.     dc.l    $7b0ffffe,$1060c40,$1be0000,$1060e40,$1be0000
  5442.     dc.l    $ac0ffffe,$1060c40,$1be098b,$1060e40,$1be0ebc    ; Restore COL31
  5443.  
  5444. IntroCopEnd    
  5445.     dc.l     $fffffffe            ; End of copperlist
  5446.  
  5447. ; *****************************************************************************
  5448. ; Chip graphics, music, etc...
  5449. ; *****************************************************************************
  5450.  
  5451.         ALIGNQUAD
  5452. SpriteData    dc.l    0,0,0,0            ; Empty sprite
  5453.  
  5454. IntroPic    incbin    "Intro.RAW"        ; 320x256x64 Intro picture
  5455.  
  5456. GameMusic    incbin    "GameMusic.MOD"        ; In-game music module
  5457. IntroMusic    incbin    "IntroMusic.MOD"    ; Intro music module
  5458.  
  5459. ; *****************************************************************************
  5460.